@ignex/ninox 0.1.6 → 0.2.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 +46 -22
- package/dist/index.d.ts +133 -102
- package/dist/index.js +840 -247
- package/dist/index.js.map +1 -1
- package/dist/{timeout-B10CTiGm.d.ts → timeout-BaP92Iyg.d.ts} +5 -15
- package/dist/utils.d.ts +4 -15
- package/dist/utils.js +91 -45
- package/dist/utils.js.map +1 -1
- package/package.json +4 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/timeout.ts","../src/capabilities.ts","../src/errors/classes.ts","../src/errors/transient.ts","../src/errors/driver-map.ts","../src/errors/http-status.ts","../src/utils/clone.ts","../src/utils/hash.ts","../src/utils/lru.ts","../src/cache/in-flight.ts","../src/cache/hot-cache/size.ts","../src/cache/hot-cache/ticker.ts","../src/cache/hot-cache/types.ts","../src/utils/watch-errors.ts","../src/cache/hot-cache/watcher.ts","../src/cache/hot-cache/index.ts","../src/cache/query-cache.ts","../src/graceful-transaction.ts","../src/hooks/hooks.ts","../src/loader/dataloader.ts","../src/migrations/types.ts","../src/migrations/files.ts","../src/migrations/journal.ts","../src/migrations/index.ts","../src/mongo-helpers.ts","../src/shared/constants.ts","../src/query-builder/query-builder.ts","../src/relation/relation.ts","../src/repository/repository.ts","../src/schema/collections.ts","../src/schema/to-mongo-schema.ts","../src/schema/types.ts","../src/schema/validate-doc/helpers.ts","../src/schema/validate-doc/field-validators.ts","../src/schema/validate-doc/validate.ts","../src/service/collection-name.ts","../src/service/connection-uri.ts","../src/service/cache-invalidation.ts","../src/utils/logger.ts","../src/service/config.ts","../src/service/connection.ts","../src/service/health.ts","../src/relation/populate.ts","../src/types.ts","../src/service/trace-db-op.ts","../src/service/op-deps.ts","../src/service/query-options.ts","../src/service/crud-op.ts","../src/service/pipeline-builder.ts","../src/service/aggregation-stages.ts","../src/service/aggregation/aggregate.ts","../src/service/aggregation/helpers.ts","../src/service/aggregation/cached-read.ts","../src/service/aggregation/group.ts","../src/service/aggregation/lookup-join.ts","../src/shared/pagination-math.ts","../src/shared/pagination-result.ts","../src/service/aggregation-pipeline.ts","../src/service/aggregation/text-search.ts","../src/service/aggregation/index.ts","../src/schema/apply-defaults.ts","../src/utils/omit-undefined.ts","../src/service/drift.ts","../src/service/update-format.ts","../src/service/crud/context.ts","../src/shared/soft-delete.ts","../src/service/crud/read-ops.ts","../src/service/crud/watch-ops.ts","../src/service/crud/write-ops.ts","../src/service/crud/index.ts","../src/shared/keyset.ts","../src/service/pagination/cursor.ts","../src/service/pagination/offset.ts","../src/service/pagination/index.ts","../src/service/schema-ops.ts","../src/service/transaction.ts","../src/service/manager.ts","../src/service/index.ts","../src/shared/merge-filters.ts","../src/shared/strip-primary-key.ts","../src/toolkit.ts","../src/utils/memoize.ts"],"names":["ObjectId","sum","deps","canonicalKey","basename","join","options","out","isPlainObject","Decimal128","Long","SEP","buildManager","meta","s","mergeAggOptions","pipeline","opts","closeConnections","prev"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Race a promise against a timeout. A `timeoutMs` <= 0 disables the timer and\n * returns the original promise untouched (zero-overhead fast path).\n */\nexport const withTimeout = <T>(\n promise: Promise<T>,\n timeoutMs: number,\n label: string,\n): Promise<T> => {\n if (timeoutMs <= 0) return promise;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n reject(new Error(`Operation timed out after ${timeoutMs}ms: ${label}`));\n }, timeoutMs);\n });\n return Promise.race([promise, timeout]).finally(() => {\n if (timer !== undefined) clearTimeout(timer);\n });\n};\n\n/**\n * Sleep helper used by retry backoff.\n *\n * `unref` (default false) detaches the timer from the event loop, so a\n * background retry loop never keeps the process alive on its own (the\n * consumer's server/sockets do that). Watcher backoff passes `unref: true`;\n * awaited query retries keep the default so a pending call is never dropped.\n */\nexport const sleep = (ms: number, unref = false): Promise<void> =>\n new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n if (unref) timer.unref?.();\n });\n\n/**\n * Sleep for `ms` plus random jitter (0..jitterMs, capped at `ms`) so retry\n * loops don't resynchronize into a thundering herd after a replica failover.\n * Accepts the same `unref` option as {@link sleep}.\n */\nexport const sleepJittered = (ms: number, jitterMs = 1000, unref = false): Promise<void> =>\n sleep(ms + Math.floor(Math.random() * Math.min(ms, jitterMs)), unref);\n","import type { Db, Document, MongoClient } from 'mongodb';\nimport { withTimeout } from './utils/timeout.ts';\n\n/**\n * Transaction capability detection. MongoDB transactions require a replica set\n * (or mongos). The ORM probes once and caches the result so the transaction\n * wrapper can fall back to plain (non-transactional) execution on standalone\n * servers.\n */\nexport interface MongoCapabilities {\n probed: boolean;\n transactionsSupported: boolean;\n}\n\nexport interface MongoCapabilitiesStore {\n get(): MongoCapabilities;\n set(capabilities: MongoCapabilities): void;\n reset(): void;\n}\n\nexport const createMongoCapabilitiesStore = (): MongoCapabilitiesStore => {\n let state: MongoCapabilities = { probed: false, transactionsSupported: false };\n return {\n get: () => state,\n set: (capabilities) => {\n state = capabilities;\n },\n reset: () => {\n state = { probed: false, transactionsSupported: false };\n },\n };\n};\n\n/** `MONGO_USE_TRANSACTIONS=1|true|yes` forces transactions on/off. */\nexport const readMongoTransactionsEnvOverride = (): boolean | undefined => {\n const raw = process.env.MONGO_USE_TRANSACTIONS;\n if (raw === undefined) return undefined;\n return ['1', 'true', 'yes'].includes(raw.toLowerCase());\n};\n\n/** Probe a connected client/db via `hello`. */\nexport const probeMongoCapabilities = async (\n client: MongoClient | Db | null | undefined,\n): Promise<MongoCapabilities> => {\n try {\n const db = client && 'startSession' in client ? (client as MongoClient).db() : (client as Db);\n if (!db) return { probed: false, transactionsSupported: false };\n const hello = await withTimeout(\n db.admin().command({ hello: 1 } as Document),\n 5_000,\n 'probeMongoCapabilities: hello',\n );\n const isReplicaSet = typeof hello.setName === 'string' && hello.setName.length > 0;\n const isMongos = hello.msg === 'isdbgrid';\n return { probed: true, transactionsSupported: isReplicaSet || isMongos };\n } catch {\n return { probed: false, transactionsSupported: false };\n }\n};\n\n/** Effective transaction support: env override → probed value → URL heuristic. */\nexport const mongoTransactionsEnabled = (\n store: MongoCapabilitiesStore,\n options: { urlHint?: string; envOverride?: boolean } = {},\n): boolean => {\n const env = options.envOverride ?? readMongoTransactionsEnvOverride();\n if (env !== undefined) return env;\n const state = store.get();\n if (state.probed) return state.transactionsSupported;\n // `mongodb+srv` seeds always resolve to a replica-set/mongos topology.\n if (options.urlHint) return /replicaSet=|mongodb\\+srv:|loadBalanced=true/i.test(options.urlHint);\n return false;\n};\n","/**\n * The ORM's error classes (`AppError` → `DomainError` / `InfraError` /\n * `BadRequest`), their type guards, and the `ERROR_HTTP_STATUS` table that sets\n * each error's `statusCode` at construction.\n *\n * A leaf module: nothing else in `src/errors/` imports this (so `driver-map.ts`\n * and `http-status.ts` can depend on it without cycles).\n */\nexport interface ErrorContext {\n db?: string;\n collection?: string;\n op?: string;\n}\n\n/**\n * Canonical HTTP status for each error code. `AppError.statusCode` is set from\n * this table at construction (falling back to the class default: 400 for\n * `DomainError`, 500 for `InfraError`), so a framework can respond with\n * `err.statusCode` directly and still get correct REST semantics:\n * NOT_FOUND → 404, DUPLICATE_KEY/VERSION_CONFLICT/COLLECTION_EXISTS → 409,\n * VALIDATION_FAILED → 422, MONGO_TIMEOUT → 504.\n */\nexport const ERROR_HTTP_STATUS: Record<string, number> = {\n BAD_REQUEST: 400,\n NOT_FOUND: 404,\n DUPLICATE_KEY: 409,\n VERSION_CONFLICT: 409,\n COLLECTION_EXISTS: 409,\n SCHEMA_DRIFT: 409,\n VALIDATION_FAILED: 422,\n MONGO_TIMEOUT: 504,\n};\n\nexport class AppError extends Error {\n readonly code: string;\n readonly statusCode: number;\n readonly extra?: Record<string, unknown>;\n\n constructor(code: string, message: string, statusCode = 500, extra?: Record<string, unknown>) {\n super(message);\n this.name = 'AppError';\n this.code = code;\n this.statusCode = statusCode;\n if (extra !== undefined) this.extra = extra;\n }\n\n /**\n * Stable, client-safe serialization for framework error middleware: a\n * framework can forward `JSON.stringify(error)` (or `error.toJSON()`) straight\n * to the client — no parsing of server internals. `stack` is dropped; the\n * shape is always `{ name, code, message, statusCode, ...(extra) }`.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n statusCode: this.statusCode,\n ...(this.extra !== undefined ? { extra: this.extra } : {}),\n };\n }\n}\n\nexport class DomainError extends AppError {\n constructor(code: string, message: string, extra?: Record<string, unknown>) {\n super(code, message, ERROR_HTTP_STATUS[code] ?? 400, extra);\n this.name = 'DomainError';\n }\n}\n\nexport class InfraError extends AppError {\n constructor(code: string, message: string, extra?: Record<string, unknown>) {\n super(code, message, ERROR_HTTP_STATUS[code] ?? 500, extra);\n this.name = 'InfraError';\n }\n}\n\nexport class BadRequest extends DomainError {\n constructor(message: string, extra?: Record<string, unknown>) {\n super('BAD_REQUEST', message, extra);\n this.name = 'BadRequest';\n }\n}\n\nexport const isAppError = (err: unknown): err is AppError => err instanceof AppError;\n\nexport const isDomainError = (err: unknown): err is DomainError => err instanceof DomainError;\n\nexport const isInfraError = (err: unknown): err is InfraError => err instanceof InfraError;\n","/**\n * Transient-error detection: which MongoDB errors are safe to retry. This is a\n * leaf module (no folder imports) so both `driver-map.ts` and `http-status.ts`\n * can depend on it without cycles.\n */\n\n/**\n * Server error codes MongoDB raises that are safe to retry (network hiccups,\n * not-primary, sharding moves, interrupted queries). Mirrors the reference set.\n *\n * Frozen + typed `ReadonlySet` so a consumer can't mutate the shared instance\n * (it is a module-level singleton, re-exported through the barrel).\n */\nexport const TRANSIENT_MONGO_ERROR_CODES: ReadonlySet<number> = Object.freeze(\n new Set<number>([\n 6, // HostUnreachable\n 7, // HostNotFound\n 89, // NetworkTimeout\n 91, // ShutdownInProgress\n 189, // PrimarySteppedDown\n 251, // NoSuchTransaction (stepdown mid-transaction)\n 262, // ExceededTimeLimit (part of the retryable transaction set)\n 9001, // SocketException\n 10058, // NotWritablePrimary (legacy server code)\n 10107, // NotWritablePrimary\n 11600, // InterruptedAtShutdown\n 11602, // InterruptedDueToReplStateChange\n 13435, // NotPrimaryNoSecondaryOk\n 13436, // NotPrimaryOrSecondary\n ]),\n);\n\nconst TRANSIENT_NAME =\n /MongoNetworkError|PoolClearedError|MongoWriteConcernError|MongoNotPrimaryError|MongoNodeIsRecoveringError|MongoNetworkTimeoutError|MongoServerSelectionError/;\n\n/** True when the error is a transient Mongo failure that retry can recover from. */\nexport const isMongoTransientError = (error: unknown): boolean => {\n if (!error || typeof error !== 'object') return false;\n const e = error as {\n name?: unknown;\n code?: unknown;\n errInfo?: unknown;\n hasErrorLabel?: unknown;\n };\n if (\n typeof e.hasErrorLabel === 'function' &&\n (e.hasErrorLabel as (label: string) => boolean)('TransientTransactionError')\n ) {\n return true;\n }\n if (typeof e.name === 'string' && TRANSIENT_NAME.test(e.name)) return true;\n if (typeof e.code === 'number' && TRANSIENT_MONGO_ERROR_CODES.has(e.code)) return true;\n return false;\n};\n\n/** True when the error is a duplicate-key violation (code 11000 / E11000 message). */\nexport const isMongoDuplicateKeyError = (error: unknown): boolean => {\n if (!error || typeof error !== 'object') return false;\n const e = error as { code?: unknown; message?: unknown };\n if (e.code === 11000) return true;\n if (typeof e.message === 'string' && /E11000|duplicate key/i.test(e.message)) return true;\n return false;\n};\n\n/**\n * True when the deployment cannot run transactions at all (standalone mongod,\n * or storage engine without retryable writes) — callers fall back to\n * non-transactional execution. Shared by BOTH fallback layers\n * (`withGracefulMongoTransaction` and the service `transaction` op) so they\n * classify identically.\n */\nexport const isTransactionUnsupportedError = (error: unknown): boolean => {\n const code = (error as { code?: unknown } | null)?.code;\n if (code === 20) return true; // IllegalOperation — \"Transaction numbers are only allowed...\"\n const message = error instanceof Error ? error.message : '';\n return (\n /Transaction numbers are only allowed/i.test(message) ||\n /transactions are not supported/i.test(message) ||\n /does not support retryable writes/i.test(message)\n );\n};\n\nconst MONGO_ERROR_NAME =\n /MongoError|MongoServerError|MongoBulkWriteError|MongoNetworkError|MongoNetworkTimeoutError|MongoWriteConcernError|MongoNotPrimaryError|MongoNodeIsRecoveringError|MongoCursorExhaustedError|PoolClearedError|MongoTopologyClosedError|MongoServerSelectionError/;\n\n/**\n * Server codes that identify an error as coming from MongoDB even when the\n * `name` is absent — writeErrors[] entries, rethrown callbacks, and plain\n * objects users pass to `mapMongoDriverError` carry only `{ code }`.\n */\nconst DRIVER_ERROR_CODES: ReadonlySet<number> = Object.freeze(\n new Set<number>([\n 20, // IllegalOperation (transactions unsupported)\n 26, // NamespaceNotFound\n 48, // NamespaceExists\n 50, // MaxTimeMSExpired\n 112, // WriteConflict\n 121, // DocumentValidationFailure\n 11000, // DuplicateKey\n 11001, // DuplicateKey (legacy)\n ...TRANSIENT_MONGO_ERROR_CODES,\n ]),\n);\n\n/**\n * True when the error is a MongoDB DRIVER error rather than an application\n * error thrown inside a callback/transaction.\n *\n * Name-based (not instanceof) on purpose: the driver instance that raised the\n * error and the one this module imports may be different copies of the\n * `mongodb` package. A known numeric server code or duplicate-key message\n * also qualifies, so nameless-but-coded shapes (`{ code: 11000 }`) are still\n * recognized; application errors with arbitrary numeric codes are not.\n */\nexport const isMongoDriverError = (error: unknown): boolean => {\n if (!error || typeof error !== 'object') return false;\n const e = error as { name?: unknown; code?: unknown; message?: unknown };\n if (typeof e.name === 'string' && MONGO_ERROR_NAME.test(e.name)) return true;\n if (typeof e.code === 'number' && DRIVER_ERROR_CODES.has(e.code)) return true;\n if (typeof e.message === 'string' && /E11000 duplicate key/i.test(e.message)) return true;\n return false;\n};\n","/**\n * Raw driver-error mapping: turn Mongo driver errors (codes 11000, 112, 50,\n * 121, bulk-write, transient) into the ORM's typed `DomainError` / `InfraError`,\n * plus `extractValidationPaths` for surfacing which `$jsonSchema` fields failed.\n */\nimport { AppError, DomainError, type ErrorContext, InfraError } from './classes.ts';\nimport {\n isMongoDriverError,\n isMongoDuplicateKeyError,\n isMongoTransientError,\n} from './transient.ts';\n\n/** Shape of a single `writeErrors[]` entry on a `MongoBulkWriteError`. */\ninterface WriteErrorLike {\n code?: number;\n errmsg?: string;\n keyPattern?: Record<string, unknown>;\n keyValue?: Record<string, unknown>;\n errInfo?: unknown;\n}\n\n/** Shape of the `errInfo` MongoDB attaches to a `$jsonSchema` validation failure (code 121). */\ninterface MongoErrInfo {\n failingDocumentId?: unknown;\n details?: {\n schemaRulesNotSatisfied?: Array<{\n propertyName?: string;\n propertiesNotSatisfied?: Array<{ propertyName?: string }>;\n /** Unknown-key violations are reported as a list here (not propertiesNotSatisfied). */\n additionalProperties?: string[];\n }>;\n };\n}\n\n/**\n * Flatten the offending field paths from a `$jsonSchema` validation error so a\n * `VALIDATION_FAILED` error can name exactly which fields were rejected.\n * Covers missing/type-mismatched properties (`propertiesNotSatisfied`) and\n * unknown-key violations (`additionalProperties`).\n */\nexport const extractValidationPaths = (errInfo: unknown): string[] => {\n if (!errInfo || typeof errInfo !== 'object') return [];\n const info = errInfo as MongoErrInfo;\n const out: string[] = [];\n for (const rule of info.details?.schemaRulesNotSatisfied ?? []) {\n if (typeof rule.propertyName === 'string') out.push(rule.propertyName);\n for (const prop of rule.propertiesNotSatisfied ?? []) {\n if (typeof prop.propertyName === 'string') out.push(prop.propertyName);\n }\n for (const prop of rule.additionalProperties ?? []) {\n if (typeof prop === 'string') out.push(prop);\n }\n }\n return [...new Set(out)];\n};\n\n/** Enrich a mapped-error context with the failing document id + offending field paths. */\nconst addValidationContext = (context: Record<string, unknown>, errInfo: unknown): void => {\n if (!errInfo || typeof errInfo !== 'object') return;\n const info = errInfo as MongoErrInfo;\n if (info.failingDocumentId !== undefined) context.documentId = info.failingDocumentId;\n const fields = extractValidationPaths(errInfo);\n if (fields.length > 0) context.fields = fields;\n if (info.details !== undefined) context.details = info.details;\n};\n\nconst isBulkWriteError = (error: unknown): boolean =>\n typeof error === 'object' &&\n error !== null &&\n 'writeErrors' in (error as { writeErrors?: unknown }) &&\n Array.isArray((error as { writeErrors?: unknown[] }).writeErrors);\n\n/**\n * Map a raw driver error to a typed DomainError/InfraError. Mirrors the sdk-db\n * mapping table (codes 11000 → DUPLICATE_KEY, 112 → VERSION_CONFLICT,\n * 50 → MONGO_TIMEOUT, 121 → VALIDATION_FAILED, everything else → MONGO_QUERY_ERROR).\n * When the error is already an AppError it is returned unchanged.\n */\nexport const mapMongoDriverError = (error: unknown, ctx: ErrorContext = {}): unknown => {\n if (error instanceof AppError) return error;\n // Application errors (e.g. a 409 ConflictError thrown inside a transaction\n // callback or a route) are NOT driver errors — passing them through keeps\n // their status/message intact. Only actual driver errors get mapped.\n if (!isMongoDriverError(error)) return error;\n\n const context: Record<string, unknown> = { ...(ctx as Record<string, unknown>) };\n if (isMongoDuplicateKeyError(error)) {\n const e = error as { keyPattern?: Record<string, unknown>; keyValue?: Record<string, unknown> };\n if (e.keyPattern) context.keyPattern = e.keyPattern;\n if (e.keyValue) context.keyValue = e.keyValue;\n return new DomainError('DUPLICATE_KEY', 'Duplicate key error', context);\n }\n\n if (isBulkWriteError(error)) {\n const first = (error as { writeErrors: WriteErrorLike[] }).writeErrors[0];\n if (first?.code === 11000) {\n if (first.keyPattern) context.keyPattern = first.keyPattern;\n if (first.keyValue) context.keyValue = first.keyValue;\n // Fixed message: the raw `errmsg` embeds stored values\n // (`E11000 ... dup key: { email: \"victim@x.com\" }`) and this message is\n // forwarded to clients via `toJSON()`/`serializeError()`.\n return new DomainError('DUPLICATE_KEY', 'Duplicate key error', context);\n }\n if (first?.code === 121) {\n addValidationContext(context, first.errInfo);\n return new DomainError('VALIDATION_FAILED', 'Document failed schema validation', context);\n }\n return new InfraError('MONGO_QUERY_ERROR', 'Bulk write failed', context);\n }\n\n const code = (error as { code?: unknown }).code;\n switch (code) {\n case 112:\n return new DomainError('VERSION_CONFLICT', 'Document version conflict', context);\n case 50:\n return new InfraError('MONGO_TIMEOUT', 'MongoDB operation timed out', context);\n case 121: {\n addValidationContext(context, (error as { errInfo?: unknown }).errInfo);\n return new DomainError('VALIDATION_FAILED', 'Document failed schema validation', context);\n }\n default:\n break;\n }\n\n if (isMongoTransientError(error)) {\n const e = error as { message?: string };\n return new InfraError('MONGO_QUERY_ERROR', e.message ?? 'Transient MongoDB error', context);\n }\n\n const msg = (error as { message?: string }).message ?? 'MongoDB query error';\n return new InfraError('MONGO_QUERY_ERROR', msg, context);\n};\n\n/** True when the error is already a mapped AppError (used by callers that opted into wrapping). */\nexport const isMappedMongoError = (error: unknown): error is AppError => error instanceof AppError;\n","/**\n * Framework-facing error helpers: `httpStatusForError` (effective HTTP status\n * for any thrown value) and `serializeError` (reduce any thrown value to a\n * stable, client-safe payload).\n */\nimport { AppError, type ErrorContext } from './classes.ts';\nimport { mapMongoDriverError } from './driver-map.ts';\nimport { isMongoTransientError } from './transient.ts';\n\n/** Effective HTTP status for any thrown value: AppError-aware, raw → 500 (503 transient). */\nexport const httpStatusForError = (err: unknown): number => {\n if (err instanceof AppError) return err.statusCode;\n if (isMongoTransientError(err)) return 503;\n return 500;\n};\n\n/**\n * Reduce any thrown value to a stable, client-safe error payload:\n * `{ name, code, message, statusCode, ...(extra) }`.\n *\n * Raw driver errors are mapped through `mapMongoDriverError` first, so a\n * framework can forward the result directly without parsing Mongo server\n * internals (`errInfo`, `writeErrors`, `keyPattern`, ...):\n *\n * app.use((err, _req, res, _next) => {\n * const payload = serializeError(err, { db, collection, op });\n * res.status(payload.statusCode).json(payload);\n * });\n */\nexport const serializeError = (err: unknown, ctx: ErrorContext = {}): Record<string, unknown> => {\n const mapped = mapMongoDriverError(err, ctx);\n if (mapped instanceof AppError) return mapped.toJSON();\n if (mapped instanceof Error) {\n return { name: mapped.name, code: 'UNKNOWN', message: mapped.message, statusCode: 500 };\n }\n return { name: 'UnknownError', code: 'UNKNOWN', message: String(mapped), statusCode: 500 };\n};\n","import {\n Binary,\n Code,\n DBRef,\n Decimal128,\n Double,\n Int32,\n Long,\n MaxKey,\n MinKey,\n ObjectId,\n Timestamp,\n} from 'mongodb';\n\n/**\n * Deep-clone a value while preserving the types `JSON.parse(JSON.stringify())`\n * would corrupt or flatten: `Date`, `ObjectId`, `RegExp`, the numeric/binary\n * BSON wrappers (`Decimal128`, `Long`, `Int32`, `Double`, `Timestamp`,\n * `Binary`, `MinKey`, `MaxKey`, `Code`, `DBRef`), and the JS containers\n * `Map` / `Set` / `Buffer` / typed arrays — without this, cached money fields\n * (`Decimal128`) or int64 values (`Long`) would clone into `{}`, and a\n * `Map` (no enumerable own properties) or `Buffer` would silently lose both\n * type and data in the generic-object fallback. Arrays and plain objects are\n * copied recursively; primitives pass through.\n * Used by the optional `clone` mode on `QueryCache` / `HotCache` so a caller\n * can't mutate a cached result and poison the shared cache.\n */\nexport const cloneDeep = <T>(value: T): T => {\n if (value instanceof Date) return new Date(value.getTime()) as T;\n if (value instanceof ObjectId) return new ObjectId(value.toHexString()) as T;\n if (value instanceof Decimal128) return Decimal128.fromString(value.toString()) as T;\n if (value instanceof Long) return Long.fromString(value.toString()) as T;\n if (value instanceof Int32) return new Int32(value.valueOf()) as T;\n if (value instanceof Double) return new Double(value.valueOf()) as T;\n // fromBits round-trips exactly; fromNumber loses low bits above 2^53.\n if (value instanceof Timestamp)\n return Timestamp.fromBits(value.getLowBits(), value.getHighBits()) as T;\n if (value instanceof Binary) {\n const bytes = Buffer.from(value.buffer);\n return new Binary(bytes, value.sub_type) as T;\n }\n if (value instanceof MinKey) return new MinKey() as T;\n if (value instanceof MaxKey) return new MaxKey() as T;\n if (value instanceof DBRef) {\n return new DBRef(value.collection, cloneDeep(value.oid), value.db) as T;\n }\n if (value instanceof Code) {\n return new Code(\n value.code,\n value.scope !== undefined ? cloneDeep(value.scope) : undefined,\n ) as T;\n }\n if (value instanceof RegExp) return new RegExp(value.source, value.flags) as T;\n if (value instanceof Map) {\n const out = new Map<unknown, unknown>();\n for (const [k, v] of value) out.set(cloneDeep(k), cloneDeep(v));\n return out as T;\n }\n if (value instanceof Set) {\n const out = new Set<unknown>();\n for (const v of value) out.add(cloneDeep(v));\n return out as T;\n }\n // Buffer first (a Uint8Array subclass); then any other typed array view.\n if (Buffer.isBuffer(value)) return Buffer.from(value) as T;\n if (ArrayBuffer.isView(value)) {\n const view = value as unknown as ArrayBufferView & { slice?: () => unknown };\n if (view instanceof DataView) {\n const bytes = view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);\n return new DataView(bytes) as T;\n }\n return typeof view.slice === 'function' ? (view.slice() as T) : value;\n }\n if (Array.isArray(value)) return value.map((item) => cloneDeep(item)) as T;\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = cloneDeep(v);\n }\n return out as T;\n }\n return value;\n};\n","/**\n * Deterministic hashing utilities used for cache keys / in-flight dedup keys.\n * `stableStringify` produces an order-insensitive serialization so two logically\n * identical filters yield the same hash regardless of key insertion order.\n */\n\ntype Primitive = string | number | boolean | bigint | null | undefined;\n\nconst isPlainObject = (v: unknown): v is Record<string, unknown> =>\n typeof v === 'object' &&\n v !== null &&\n !Array.isArray(v) &&\n !(v instanceof Date) &&\n !(v instanceof RegExp) &&\n // Mongo driver ObjectId (and other BSON values with a toHexString marker)\n // must fall through to `toPrimitive` — treating them as plain objects\n // would serialize every ObjectId as `{}` and collapse distinct values.\n typeof (v as { toHexString?: unknown }).toHexString !== 'function';\n\nconst toPrimitive = (v: unknown): Primitive => {\n if (v === undefined || v === null) return null;\n if (typeof v === 'bigint') return v.toString();\n if (v instanceof Date) return `date:${v.getTime()}`;\n if (typeof v === 'object') {\n // Mongo driver ObjectId has toHexString(); RegExp serializes as a string.\n const anyV = v as { toHexString?: () => string; source?: string; flags?: string };\n if (typeof anyV.toHexString === 'function') return `oid:${anyV.toHexString()}`;\n if (anyV instanceof RegExp) return `re:${anyV.source}/${anyV.flags}`;\n }\n return v as Primitive;\n};\n\n/**\n * Stable stringify: recursively sorts object keys, coerces Date/ObjectId/RegExp\n * into primitive markers. Result is deterministic for a given logical value.\n */\nexport const stableStringify = (value: unknown): string => {\n const visit = (v: unknown): Primitive | Record<string, unknown> | unknown[] => {\n if (Array.isArray(v)) return v.map(visit);\n if (isPlainObject(v)) {\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(v).sort()) out[key] = visit(v[key]);\n return out;\n }\n return toPrimitive(v);\n };\n return JSON.stringify(visit(value));\n};\n\n/**\n * Dual-round 32-bit digest → ~64 bits of collision resistance, base-36.\n * Round 1 is djb2; round 2 mixes FNV-1a over the same input so two distinct\n * strings colliding in one round almost never collide in both. Cache keys\n * store ONLY this digest, so collision resistance matters: a hit must never\n * be able to serve another query's rows.\n */\nexport const hashString = (input: string): string => {\n let h1 = 5381;\n let h2 = 0x811c9dc5;\n for (let i = 0; i < input.length; i++) {\n const c = input.charCodeAt(i);\n h1 = ((h1 << 5) + h1 + c) | 0;\n h2 = ((h2 ^ c) * 0x01000193) | 0;\n // Extra diffusion so low-entropy inputs still spread across rounds.\n h2 = (h2 << 3) | (h2 >>> 29);\n }\n return `${(h1 >>> 0).toString(36)}${(h2 >>> 0).toString(36)}`;\n};\n\n/** Convenience: hash any value through a stable stringification. */\nexport const stableHash = (value: unknown): string => hashString(stableStringify(value));\n","/**\n * Minimal dependency-free LRU cache backed by a Map (recency = insertion order).\n * get() re-inserts the entry so the most-recently-used item is always last.\n */\nexport interface LRUOptions {\n /** Maximum number of entries before the least-recently-used item is evicted. Must be > 0. */\n max: number;\n /**\n * Called when an entry is evicted by capacity pressure (NOT on explicit\n * delete/clear). Lets owners release side structures keyed by the entry.\n */\n onEvict?: (key: never, value: never) => void;\n}\n\nexport class LRU<K, V> {\n readonly max: number;\n private map = new Map<K, V>();\n private onEvict: ((key: K, value: V) => void) | undefined;\n /** Number of entries evicted to make room for new ones (capacity evictions only). */\n evictions = 0;\n\n constructor(options: LRUOptions) {\n if (options.max <= 0) throw new Error('LRU max must be > 0');\n this.max = options.max;\n // Contravariance-safe: `(key: never) => void` accepts any handler shape.\n this.onEvict = options.onEvict as ((key: K, value: V) => void) | undefined;\n }\n\n get size(): number {\n return this.map.size;\n }\n\n get(key: K): V | undefined {\n const value = this.map.get(key);\n if (value === undefined) return undefined;\n // Refresh recency.\n this.map.delete(key);\n this.map.set(key, value);\n return value;\n }\n\n peek(key: K): V | undefined {\n return this.map.get(key);\n }\n\n has(key: K): boolean {\n return this.map.has(key);\n }\n\n set(key: K, value: V): this {\n if (this.map.has(key)) this.map.delete(key);\n this.map.set(key, value);\n if (this.map.size > this.max) {\n const next = this.map.keys().next();\n if (next.done !== true) {\n const evictedKey = next.value;\n const evictedValue = this.map.get(evictedKey) as V;\n this.map.delete(evictedKey);\n this.evictions++;\n try {\n // Eviction hooks must never break the cache write path.\n this.onEvict?.(evictedKey, evictedValue);\n } catch {\n /* ignore */\n }\n }\n }\n return this;\n }\n\n delete(key: K): boolean {\n return this.map.delete(key);\n }\n\n clear(): void {\n this.map.clear();\n }\n\n keys(): IterableIterator<K> {\n return this.map.keys();\n }\n\n entries(): IterableIterator<[K, V]> {\n return this.map.entries();\n }\n\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.map.entries();\n }\n}\n","/**\n * In-flight request coalescing: identical concurrent operations share a single\n * Promise so the underlying (expensive) work runs once. This is the \"query\n * dedup\" optimization used by the CRUD read path.\n */\nexport class InFlight {\n private pending = new Map<string, Promise<unknown>>();\n\n get size(): number {\n return this.pending.size;\n }\n\n run<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const existing = this.pending.get(key);\n if (existing) return existing as Promise<T>;\n let promise: Promise<T>;\n try {\n // Call fn() SYNCHRONOUSLY (instead of Promise.resolve().then(fn)) so\n // the caller chain — route handler → ORM → hot-cache get/fetch — stays\n // on the stack for the ignex debugbar's span-origin capture. A detached\n // .then() microtask unwinds that chain, so origins truncate at this\n // wrapper and never reach the application code that issued the query.\n // Promise.resolve() still normalizes sync returns; the try/catch keeps\n // the old contract of turning a synchronous throw into a rejection.\n promise = Promise.resolve(fn());\n } catch (err) {\n promise = Promise.reject(err) as Promise<T>;\n }\n // Cleanup as a DETACHED side-chain: wrapping the returned promise in\n // .finally() would make Bun truncate the async chain at this wrapper and\n // hide the route handler from span origins again. Both handlers consume\n // the settlement so a rejected loader never surfaces as an unhandled\n // rejection.\n promise.then(\n () => {\n this.pending.delete(key);\n },\n () => {\n this.pending.delete(key);\n },\n );\n this.pending.set(key, promise);\n return promise;\n }\n\n clear(): void {\n this.pending.clear();\n }\n}\n","/**\n * Cheap, BSON-aware byte estimator used by the HotCache `maxValueBytes` guard.\n * It is deliberately approximate (strings 2 bytes/char, fixed sizes for\n * primitives/BSON kinds) — enough to reject pathologically large values without\n * the cost of a real BSON encoder.\n *\n * Coverage notes: `Map`/`Set`/typed arrays are measured (a loader returning a\n * big Map used to measure 0 bytes and bypass the guard entirely), and a\n * `seen` WeakSet makes cyclic structures safe (they report their traversed\n * size instead of crashing with a stack overflow inside `fetch`).\n */\nimport { ObjectId } from 'mongodb';\n\nconst OVERHEAD_PER_KEY = 8;\n\n/** Approximate in-memory byte size of a cached value (used to bound single entries). */\nexport const estimateSize = (value: unknown, seen?: WeakSet<object>): number => {\n if (value === null || value === undefined) return 0;\n if (typeof value === 'string') return value.length * 2;\n if (typeof value === 'number' || typeof value === 'boolean') return 8;\n if (typeof value === 'bigint') return 16;\n if (typeof value !== 'object') return 0;\n if (value instanceof ObjectId) return 16;\n if (value instanceof Date) return 8;\n\n const visit = (v: unknown): number => {\n // Cycle guard: revisit only counts the reference overhead once.\n if (v !== null && typeof v === 'object') {\n if (!seen) seen = new WeakSet();\n else if (seen.has(v as object)) return OVERHEAD_PER_KEY;\n seen.add(v as object);\n }\n return estimateSize(v, seen);\n };\n\n if (Array.isArray(value)) {\n let sum = OVERHEAD_PER_KEY * Math.max(value.length, 1);\n for (const v of value) sum += visit(v);\n return sum;\n }\n if (value instanceof Map) {\n let sum = OVERHEAD_PER_KEY * value.size;\n for (const [k, v] of value) sum += estimateSize(k, seen) + visit(v);\n return sum;\n }\n if (value instanceof Set) {\n let sum = OVERHEAD_PER_KEY * value.size;\n for (const v of value) sum += visit(v);\n return sum;\n }\n if (ArrayBuffer.isView(value)) {\n // Buffers/typed arrays: measure REAL bytes — iterating them as index-keyed\n // objects inflated the estimate ~10× and caused spurious sizeSkips.\n return (value as ArrayBufferView).byteLength + OVERHEAD_PER_KEY;\n }\n let sum = 0;\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n sum += k.length * 2 + OVERHEAD_PER_KEY + visit(v);\n }\n return sum;\n};\n","/**\n * Standalone-mode background refresh: a single global `setInterval` ticker that\n * re-runs the loaders of due entries and swaps the fresh values in. Stale values\n * keep being served until the swap (bounded staleness, reads never block).\n *\n * A strategy object owned by `HotCache` (see `./index.ts`); the host supplies\n * the registered queries, the fetch pipeline, and the logger via `TickerHost`.\n */\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport type { RegisteredQuery } from './types.ts';\n\nexport interface TickerHost {\n /** All registered queries (the ticker mutates their counters/refresh timestamps). */\n queries: () => Map<string, RegisteredQuery>;\n /** The shared read-through fetch pipeline (with in-flight dedup + gen guard). */\n fetch: (\n q: RegisteredQuery,\n key: string,\n args: readonly unknown[],\n gen: number,\n ) => Promise<unknown>;\n logger: LoggerLike;\n}\n\n/** Max loader kicks a single tick may launch (stampede guard after downtime). */\nconst MAX_TICK_INFLIGHT = 64;\n\n/** Global standalone refresh ticker. Owns the timer; stops cleanly via `stop()`. */\nexport class RefreshTicker {\n private timer: ReturnType<typeof setInterval> | undefined;\n private intervalMs: number;\n\n constructor(\n private host: TickerHost,\n tickIntervalMs: number,\n ) {\n this.intervalMs = tickIntervalMs;\n }\n\n /** Whether the timer is currently running. */\n get running(): boolean {\n return this.timer !== undefined;\n }\n\n /** Start the interval (idempotent). The timer is `.unref()`'d so it never holds the process open. */\n start(): void {\n if (this.timer) return;\n this.timer = setInterval(() => {\n try {\n this.tick();\n } catch (err) {\n this.host.logger.warn?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'hot cache tick failed',\n );\n }\n }, this.intervalMs);\n // Don't keep the process alive on a lone timer (serverless/CLI friendly).\n const t = this.timer as { unref?: () => unknown } | undefined;\n t?.unref?.();\n }\n\n /** Stop the interval (idempotent). */\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n /**\n * Background refresh pass: re-run loaders for due entries, swap fresh values.\n * A per-tick in-flight budget bounds the stampede after downtime/throttling —\n * one sweep can't launch unbounded simultaneous loaders across all queries;\n * skipped entries stay due and are picked up by the next tick.\n */\n private tick(): void {\n const now = Date.now();\n let budget = MAX_TICK_INFLIGHT;\n for (const q of this.host.queries().values()) {\n if (q.refreshIntervalMs <= 0) continue;\n for (const [key, entry] of [...q.lru.entries()]) {\n if (entry.nextRefreshAt <= now) {\n if (budget <= 0) return;\n budget--;\n // Claim the slot BEFORE kicking so duplicate ticks joining the same\n // in-flight load don't inflate the refreshes counter; on failure the\n // catch resets `nextRefreshAt` (to `now`, not tick-start time).\n entry.nextRefreshAt = now + q.refreshIntervalMs;\n q.refreshes++;\n void this.host.fetch(q, key, entry.args, q.gen).catch((err) => {\n const current = q.lru.peek(key);\n if (current) current.nextRefreshAt = Date.now();\n this.host.logger.warn?.(\n {\n error: err instanceof Error ? err.message : String(err),\n query: q.name,\n },\n 'hot cache background refresh failed (stale value retained)',\n );\n });\n }\n }\n }\n }\n\n /**\n * In standalone mode the ticker only refreshes queries with an explicit\n * `refreshIntervalMs`. A query with neither `refreshIntervalMs` nor `ttlMs`\n * set is served until it is manually invalidated — an easy way to serve\n * unbounded-stale data. Surface those queries once so the operator opts in\n * deliberately.\n */\n warnUnboundedStaleness(): void {\n const unbounded = [...this.host.queries().values()].filter(\n (q) => q.refreshIntervalMs <= 0 && q.ttlMs <= 0,\n );\n if (unbounded.length === 0) return;\n this.host.logger.warn?.(\n { queries: unbounded.map((q) => q.name) },\n 'hot cache: standalone mode — these queries have no refreshIntervalMs/ttlMs, so values are served until manually invalidated (unbounded staleness); set refreshIntervalMs or ttlMs to bound it',\n );\n }\n}\n","/**\n * Types + constants for the HotCache layer. All type-only (plus the stream-key\n * separator constant), so the coordinating class (`HotCache` in `./index.ts`)\n * and its strategy modules (`./ticker.ts`, `./watcher.ts`) share one vocabulary\n * without importing each other's runtime logic.\n */\nimport type { Db } from 'mongodb';\nimport { stableStringify } from '../../utils/hash.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport type { LRU } from '../../utils/lru.ts';\n\n/** Separator used in stream/dedupe keys so names can't collide across parts. */\nexport const WATCH_SEP = '\\u0000';\n\n/** A collection to watch for invalidation. `collection` is the PHYSICAL name. */\nexport interface HotCollectionRef {\n /**\n * Raw `Db` handle (e.g. `service.db.primaryClient.client`) — or a lazy\n * `() => Db` accessor resolved when the watcher starts. The lazy form lets\n * apps register queries at module scope (before the connection exists) and\n * only touch the live handle at `start()` time.\n */\n db: Db | (() => Db);\n /** Physical collection name whose writes invalidate bound queries. */\n collection: string;\n /**\n * Fine-tuned invalidation: extract the document ids (or groups of ids) that\n * one loader call's arguments depend on. Without this, ANY write to the\n * collection purges every entry of every query bound to it; with it, a\n * change-stream event (replica mode) or a manual\n * `invalidateIds(collection, [id])` call purges ONLY the entries that\n * extracted this id — sibling entries stay warm.\n *\n * Return every id the result depends on (one per document, or many for\n * grouped/aggregated results). Ids may be strings, numbers, ObjectIds… —\n * they are compared after stable normalization, so an ObjectId and its hex\n * string match.\n *\n * Must be pure and cheap (it runs once per load). If it throws or returns a\n * non-array the entry is marked conservative: it is dropped by ANY targeted\n * change on that collection instead of being kept incorrectly.\n *\n * Typed as `never`-params (contravariance-safe, same trick as `LRU`'s\n * `onEvict`): declare your own parameter types and they line up with the\n * query's loader args — `idsOf: (team: string) => members(team)`.\n */\n idsOf?: (...args: never) => readonly unknown[];\n}\n\n/** Resolve a possibly-lazy collection ref to its live `Db` handle. */\nexport const resolveWatchDb = (ref: HotCollectionRef): Db =>\n typeof ref.db === 'function' ? (ref.db as () => Db)() : ref.db;\n\n/**\n * Normalize a watched document id into a comparable key so an id passed to\n * `invalidateIds` matches the same id extracted by `idsOf` regardless of\n * representation: an ObjectId and its 24-char hex string collapse to the same\n * key, numbers/bigints to their decimal form, Dates to an epoch marker.\n * Anything else falls back to a stable serialization. Over-matching is safe by\n * design — worst case one extra entry is purged.\n */\nexport const normalizeWatchId = (id: unknown): string => {\n if (typeof id === 'string') return id;\n if (typeof id === 'number' || typeof id === 'bigint') return String(id);\n if (id instanceof Date) return `d${id.getTime()}`;\n const hex =\n typeof id === 'object' && id !== null\n ? (id as { toHexString?: () => string }).toHexString\n : undefined;\n if (typeof hex === 'function') return hex.call(id); // ObjectId → hex string\n return stableStringify(id);\n};\n\n/** Opt-in query registration. `TArgs` = the parameter tuple, `TResult` = loader result. */\nexport interface HotQueryConfig<TArgs extends readonly unknown[], TResult> {\n /** Read-through loader executed on cache miss / background refresh. */\n loader: (...args: TArgs) => Promise<TResult>;\n /**\n * Optional cache-key extractor. Lets callers decide which parameters form the\n * key (e.g. hash only some of them). Default: `stableHash` of all arguments.\n */\n keyOf?: (...args: TArgs) => string;\n /** Per-query TTL in ms (`0` = no expiry). Defaults to `defaultTtlMs`. */\n ttlMs?: number;\n /** Per-query LRU cap. Defaults to `defaultMaxSize`. */\n maxSize?: number;\n /**\n * Background refresh interval in ms (standalone ticker only). Default `0` =\n * no background refresh — entries then update only via `ttlMs` expiry or\n * manual `invalidate*` calls. In standalone mode with `autoRefresh` on, a\n * query with neither `refreshIntervalMs` nor `ttlMs` set serves values until\n * it is manually invalidated (unbounded staleness); `start()` logs a warning\n * naming those queries so you can opt in deliberately.\n */\n refreshIntervalMs?: number;\n /**\n * Collections whose data changes invalidate this query. Used by replica mode\n * to open change-stream watchers. In standalone mode these have no effect\n * (the ticker refreshes instead) — use `invalidateCollection` manually if\n * needed.\n */\n watch?: HotCollectionRef[];\n /**\n * Clone results on every read so callers can't mutate the shared cached entry\n * (default false — cloning has a per-read cost; treat cached results as\n * read-only when disabled).\n */\n clone?: boolean;\n /**\n * Upper bound (bytes) for a cached value, estimated via a cheap BSON-aware\n * size probe. Larger values are still returned to the caller but are NOT\n * cached (a first oversized result logs a warning). Protects the LRU from\n * holding unbounded single entries. Default: no limit.\n */\n maxValueBytes?: number;\n}\n\nexport interface HotCacheOptions {\n /**\n * Replica-support probe. Default: `probeMongoCapabilities` over the first\n * watched collection's `db`. Return `true` → change-stream mode,\n * `false` → standalone ticker mode. A probe that returns no result (timeout)\n * falls back to standalone with a warning — pass `mode` to pin the behavior.\n */\n probe?: () => Promise<boolean>;\n /**\n * Pin the cache mode directly, skipping the probe entirely. `'replica'` opens\n * change-stream watchers, `'standalone'` starts the ticker. Useful when the\n * deployment is known (e.g. from connection config) and you want to avoid a\n * `hello` round-trip or a mis-detection.\n */\n mode?: 'replica' | 'standalone';\n /** Default per-query TTL in ms (`0` = no expiry). Default `0`. */\n defaultTtlMs?: number;\n /** Default per-query LRU cap. Default `500`. */\n defaultMaxSize?: number;\n /** Global ticker interval in ms (standalone mode). Default `1000`. */\n tickIntervalMs?: number;\n /**\n * Master switch for the standalone background-refresh ticker. `true` (default)\n * runs the global ticker that re-fetches entries at `refreshIntervalMs`. Set\n * `false` to turn off auto-refetch entirely — data then updates only via\n * manual `invalidate`/`invalidateParams`/`invalidateCollection` or `ttlMs`\n * expiry. Replica-mode change streams are event-driven and unaffected.\n */\n autoRefresh?: boolean;\n logger?: LoggerLike;\n}\n\nexport type HotCacheMode = 'unknown' | 'replica' | 'standalone';\n\n/** Typed handle returned by `register` — type-safe alternative to dynamic `get`. */\nexport interface HotQueryAccessor<TArgs extends readonly unknown[], TResult> {\n /** Read-through: serve from LRU, else run the loader. */\n get: (...args: TArgs) => Promise<TResult>;\n /**\n * Manual invalidation (fully typed, with intellisense on the parameters).\n * Called with no arguments it drops every cached entry for this query; called\n * with the query's parameters it drops only that parameter's entry.\n *\n * topProducts.invalidate(); // drop all\n * topProducts.invalidate(10); // drop only the { limit: 10 } entry\n */\n invalidate: {\n (): void;\n (...args: TArgs): void;\n };\n}\n\n/** One cached value + the bookkeeping that drives expiry / background refresh. */\nexport interface Entry {\n value: unknown;\n args: readonly unknown[];\n expiresAt: number;\n nextRefreshAt: number;\n /**\n * Namespaced watched-document dependencies (`${collection}${WATCH_SEP}${id}`)\n * extracted via each watch ref's `idsOf` at store time — what id-targeted\n * invalidation matches against. Empty = the extractor listed no ids for this\n * call, so targeted changes keep the entry (TTL/ticker/manual still apply).\n */\n deps?: readonly string[];\n /**\n * Conservative marker set when dependency extraction threw or returned a\n * non-array: the entry is dropped by ANY targeted change on its watched\n * collections (never kept incorrectly).\n */\n depsAll?: boolean;\n}\n\n/** Runtime state for one registered query (owned by `HotCache`, mutated by ticker/watcher). */\nexport interface RegisteredQuery {\n name: string;\n config: HotQueryConfig<readonly unknown[], unknown>;\n lru: LRU<string, Entry>;\n ttlMs: number;\n refreshIntervalMs: number;\n clone: boolean;\n maxValueBytes?: number;\n /** Precomputed at register time: any watch ref declares an `idsOf` extractor. */\n hasIdWatch: boolean;\n /** Bumped on every invalidation/clear so in-flight loads don't re-store stale data. */\n gen: number;\n hits: number;\n misses: number;\n refreshes: number;\n loadErrors: number;\n sizeSkips: number;\n /** Entries dropped by id-targeted invalidation (`invalidateIds` / change events). */\n idDrops: number;\n warnedSize: boolean;\n}\n\n/** Per-query runtime counters (see `HotCache.stats()`). */\nexport interface HotQueryStats {\n /** Current number of cached entries for this query. */\n size: number;\n /** Reads served from the LRU without running the loader. */\n hits: number;\n /** Reads that ran the loader (LRU miss or expired entry). */\n misses: number;\n /** Background refreshes kicked by the standalone ticker. */\n refreshes: number;\n /** Loader rejections (failed reads/refreshes). */\n loadErrors: number;\n /** Values too large to cache (`maxValueBytes`). */\n sizeSkips: number;\n /** Entries dropped by id-targeted invalidation (`invalidateIds` / change events). */\n idDrops: number;\n /** Capacity evictions (LRU). */\n evictions: number;\n}\n\n/** Snapshot of the whole cache (see `HotCache.stats()`). */\nexport interface HotCacheStats {\n mode: HotCacheMode;\n /** Number of registered queries. */\n queries: number;\n /** Total cached entries across all queries. */\n entries: number;\n perQuery: Record<string, HotQueryStats>;\n}\n","/**\n * Permanent change-stream error classification, shared by every `$changeStream`\n * watcher (service `CacheInvalidator` + hot-cache `WatchCoordinator`).\n *\n * These errors can NEVER be fixed by retrying — retrying only logs the same\n * warning every 1–5s forever and (with an un-unref'd timer) keeps the process\n * alive, which is wrong for a background watcher whose host server or build\n * should own the process lifetime. Watchers must classify them once, log once,\n * and stop (disable the watcher / fall back to the standalone ticker).\n *\n * Deliberately NARROW on purpose: replica errors that ARE transient — e.g.\n * \"change stream history lost\" (resume-token expiry, collection dropped),\n * network drops, failovers — must stay in the retry path, where\n * invalidate-on-reopen restores correctness. Broad patterns (like `not\n * supported` or `ChangeStream`) are rejected here because they can misfire on\n * those recoverable errors.\n */\nexport const isPermanentWatchError = (message: string): boolean =>\n // Standalone server: `$changeStream` is not supported at all.\n /only supported on replica sets/i.test(message) ||\n // Credentials/authorization problems: the user cannot run `aggregate` on\n // this collection/server. Wrong creds, missing roles, or a user created\n // without the `read`/`changeStream` privilege will never start working by\n // retrying — fail once and stop instead of retrying forever.\n /requires authentication|not authorized|unauthorized|authentication failed|Command .* requires authentication/i.test(\n message,\n );\n","/**\n * Replica-mode change-stream watchers: one long-lived `$changeStream` consumer\n * per (database, collection); every data change invalidates the queries bound\n * to that collection (event-driven, works across processes and external\n * writers). Document events are routed through `invalidateDocument` so queries\n * with an `idsOf` extractor purge only the entries depending on that document;\n * stream-wide events (drop/rename/invalidate) and reconnects invalidate the\n * whole collection.\n *\n * A strategy object owned by `HotCache` (see `./index.ts`). The host supplies\n * the registered queries, per-collection invalidation, and the mode-fallback\n * callback. On permanent \"not supported\" errors the watcher drops the stream\n * and, when every planned stream has failed, tells the host to flip to the\n * standalone ticker. Transient errors retry with jittered backoff.\n *\n * ## Failure semantics (the staleness window)\n *\n * `watchLoop` is the self-healing consumer. Any stream error or server-side\n * kill (network drop, replica failover, cursor invalidation) is logged, the\n * abandoned stream is closed, and the loop reconnects after a jittered backoff\n * (1s → 5s). On every REOPEN (`backoff > 0`) the bound collection is\n * invalidated **once**, dropping cached entries so anything written during the\n * outage is re-fetched on the next read — this \"invalidate-on-reopen\" is what\n * restores correctness after:\n *\n * - **Resume-token expiry** — a `ChangeStreamHistoryLost`/invalid-token error.\n * It is a recoverable error, NOT \"not supported\", so it stays in the retry\n * path. The re-opened stream has no resume token and starts from \"now\"; the\n * invalidate-on-reopen drops entries that could be stale.\n * - **Rollback / `invalidate` events** — a dropped or renamed collection emits\n * an `invalidate` event that ends the stream; the loop reconnects and\n * invalidates on reopen.\n * - **Consumer downtime** — while the consumer is down, writes are NOT\n * observed, so the in-process LRU keeps serving stale values (the inherent\n * tradeoff: low latency can hide stale reads). Staleness is bounded only by\n * reconnect latency + the invalidate-on-reopen, plus any per-query\n * `ttlMs`/`refreshIntervalMs`. A consumer that never reconnects leaves\n * entries stale forever unless TTL/refresh are set.\n */\nimport type { ChangeStream, Db } from 'mongodb';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { sleepJittered } from '../../utils/timeout.ts';\nimport { isPermanentWatchError } from '../../utils/watch-errors.ts';\nimport { type HotCollectionRef, type RegisteredQuery, resolveWatchDb, WATCH_SEP } from './types.ts';\n\nexport interface WatchHost {\n /** All registered queries (their `watch` refs drive which streams to open). */\n queries: () => Map<string, RegisteredQuery>;\n /** Invalidate every query bound to a physical collection. */\n invalidateCollection: (collection: string) => void;\n /**\n * Invalidate only the entries that depend on one changed document (the\n * change event's `documentKey._id`). The host decides per query whether it\n * can target by id (`idsOf`) or must fall back to a coarse purge.\n */\n invalidateDocument: (collection: string, id: unknown) => void;\n /** Whether the cache is currently in replica mode (used before a fallback). */\n isReplica: () => boolean;\n /** Flip the cache to standalone mode + start the ticker (called after a total fallback). */\n fallbackToStandalone: () => void;\n logger: LoggerLike;\n}\n\n/**\n * Resolve a lazy `db` accessor defensively: module-scope registrations commonly\n * access connections that don't exist yet, so a THROW means \"not available\n * yet\" — never let it escape into an unhandled rejection.\n */\nconst resolveDbSafe = (ref: HotCollectionRef, logger: LoggerLike): Db | null => {\n try {\n return resolveWatchDb(ref);\n } catch (err) {\n logger.debug?.(\n { error: err instanceof Error ? err.message : String(err), collection: ref.collection },\n 'hot cache: watch db accessor not ready yet',\n );\n return null;\n }\n};\n\n/**\n * The `_id` of the document a change event touched, or `undefined` for\n * stream-wide events (drop / dropDatabase / rename / invalidate) that carry no\n * `documentKey` and must invalidate the whole collection. Real `_id` values are\n * never undefined — but they CAN be falsy (`0`, `''`), hence the explicit\n * null-check on the wrapper object instead of the id itself.\n */\nconst documentKeyOf = (change: unknown): unknown => {\n const key = (change as { documentKey?: { _id?: unknown } | null } | null | undefined)\n ?.documentKey;\n return key ? key._id : undefined;\n};\n\n/** Long-lived change-stream coordinator for replica mode. */\nexport class WatchCoordinator {\n private streams = new Map<string, ChangeStream>();\n private failedStreams = new Set<string>();\n private stopped = true;\n /** Guards against stacking reconnect timers when several accessors lag. */\n private reopenTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(private host: WatchHost) {}\n\n /** Number of currently open change streams. */\n get size(): number {\n return this.streams.size;\n }\n\n /** Mark the coordinator as running and open watchers for all watch refs (idempotent). */\n start(): void {\n this.stopped = false;\n this.openWatchStreams();\n }\n\n /** Close every watcher and clear failure bookkeeping (idempotent). */\n async stop(): Promise<void> {\n this.stopped = true;\n if (this.reopenTimer) clearTimeout(this.reopenTimer);\n const closes = [...this.streams.values()].map((stream) => {\n try {\n return Promise.resolve(stream.close()).catch(() => {});\n } catch {\n return Promise.resolve();\n }\n });\n this.streams.clear();\n this.failedStreams.clear();\n await Promise.allSettled(closes);\n }\n\n private openWatchStreams(): void {\n const seen = new Set<string>();\n let deferred = false;\n for (const q of this.host.queries().values()) {\n for (const ref of q.config.watch ?? []) {\n const db = resolveDbSafe(ref, this.host.logger);\n // Accessor not ready yet (module-scope registration before connect):\n // retry the whole sweep shortly instead of losing the stream forever.\n if (!db) {\n deferred = true;\n continue;\n }\n const key = `${db.databaseName}${WATCH_SEP}${ref.collection}`;\n if (seen.has(key) || this.streams.has(key)) continue;\n seen.add(key);\n // The loop must NEVER float as an unhandled rejection — any escape\n // from its catch handler would crash the process (Node ≥ 15).\n void this.watchLoop(key, ref).catch((err) => {\n this.host.logger.error?.(\n { error: err instanceof Error ? err.message : String(err), collection: ref.collection },\n 'hot cache: watcher crashed',\n );\n });\n }\n }\n if (deferred && !this.stopped && !this.reopenTimer) {\n this.reopenTimer = setTimeout(() => {\n this.reopenTimer = undefined;\n if (!this.stopped) this.openWatchStreams();\n }, 5_000);\n this.reopenTimer.unref?.();\n }\n }\n\n /**\n * Long-lived change-stream consumer for one collection. Each data change\n * invalidates the queries bound to it. On permanent \"not supported\" errors the\n * watcher is dropped and, if every planned stream failed, the cache falls back\n * to the standalone ticker. Transient errors (including resume-token expiry,\n * rollbacks, and `invalidate` events) retry with backoff and invalidate the\n * collection on reopen so entries missed during the outage are re-fetched —\n * see the module doc for the full failure-semantics contract.\n */\n private async watchLoop(key: string, ref: HotCollectionRef): Promise<void> {\n let backoff = 0;\n while (!this.stopped) {\n // A stream that stayed healthy for a long time before failing is an\n // isolated blip — reset the escalation instead of converging to 5s\n // forever (backoff is for repeated failures, not for uptime history).\n let connectedAt = Date.now();\n try {\n const db = resolveDbSafe(ref, this.host.logger);\n if (!db) throw new Error('watch db accessor not available');\n const stream = db.collection(ref.collection).watch([]);\n stream.on('error', (err: unknown) => {\n // Prevent EventEmitter crashes between events; keep diagnostics.\n this.host.logger.debug?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'hot cache change stream error event',\n );\n });\n this.streams.set(key, stream);\n connectedAt = Date.now();\n if (backoff > 0) {\n // This stream is a RECONNECT after an error — changes made during the\n // outage were missed, so drop any entries they may have affected.\n this.host.logger.warn?.(\n { collection: ref.collection },\n 'hot cache: change stream reconnected — invalidating collection to drop entries missed during the outage',\n );\n this.host.invalidateCollection(ref.collection);\n }\n const iterator = stream[Symbol.asyncIterator]();\n for await (const change of iterator) {\n // Document events carry `documentKey._id` → targeted purge of just\n // the entries depending on that document (queries without an\n // `idsOf` extractor still get the coarse collection-wide drop, see\n // HotCache.invalidateIds). Anything else (drop/rename/invalidate)\n // purges the whole collection.\n const docId = documentKeyOf(change);\n if (docId === undefined) this.host.invalidateCollection(ref.collection);\n else this.host.invalidateDocument(ref.collection, docId);\n }\n } catch (err) {\n if (Date.now() - connectedAt > 60_000) backoff = 0;\n const message = err instanceof Error ? err.message : String(err);\n this.host.logger.warn?.(\n { error: message, collection: ref.collection },\n 'hot cache change stream error',\n );\n // Close the abandoned stream before the retry loop re-opens one, so a\n // transient error never leaks a ChangeStream cursor.\n const abandoned = this.streams.get(key);\n this.streams.delete(key);\n if (abandoned) {\n try {\n await abandoned.close();\n } catch {\n // Best-effort: the server drops the cursor on disconnect anyway.\n }\n }\n // Classify permanent errors ONLY by the definitive standalone + auth\n // verdicts (see isPermanentWatchError). A broad pattern (e.g. `not\n // supported` or `ChangeStream`) can misfire on replica errors like\n // \"change stream history lost\" (resume-token expiry) and wrongly flip\n // the cache to the standalone ticker — those must stay in the retry\n // path, where the invalidate-on-reopen restores correctness.\n if (isPermanentWatchError(message)) {\n this.markStreamFailed(key);\n return;\n }\n }\n if (this.stopped) return;\n backoff = Math.min(backoff + 1000, 5000);\n await sleepJittered(backoff, 1000, true);\n }\n }\n\n private markStreamFailed(key: string): void {\n this.failedStreams.add(key);\n if (!this.host.isReplica()) return;\n const planned = this.plannedStreamKeys();\n if (planned.size > 0 && [...planned].every((k) => this.failedStreams.has(k))) {\n this.host.logger.warn?.({}, 'hot cache: change streams unsupported, falling back to ticker');\n this.host.fallbackToStandalone();\n }\n }\n\n private plannedStreamKeys(): Set<string> {\n const set = new Set<string>();\n for (const q of this.host.queries().values()) {\n for (const ref of q.config.watch ?? []) {\n const db = resolveDbSafe(ref, this.host.logger);\n if (!db) continue; // accessor not ready — not a \"failed\" stream\n set.add(`${db.databaseName}${WATCH_SEP}${ref.collection}`);\n }\n }\n return set;\n }\n}\n","/**\n * HotCache — read-through hot cache for latency-sensitive, high-throughput\n * workloads that cannot afford a DB round-trip on every read.\n *\n * A user creates ONE global instance via `createHotCache()`, opts-in (\"registers\")\n * the queries that should be served from memory, and the parameters of each call\n * become the cache key. Reads hit a per-query LRU; misses run the user's loader\n * exactly once (concurrent identical calls are in-flight-deduped).\n *\n * Keeping the cache fresh is deployment-dependent, chosen by probing whether the\n * MongoDB deployment supports replica sets:\n * - **Replica set / mongos** → change-stream watchers (`./watcher.ts`) are\n * opened on the collections each query is bound to (`watch`). Any\n * insert/update/delete invalidates the affected queries immediately\n * (event-driven, works across processes, covers external writers). When a\n * watch ref declares `idsOf`, the changed document's `_id` is matched\n * against the dependencies each cached entry extracted from its arguments,\n * so only entries that actually depend on the changed document are purged.\n * - **Standalone** (no change streams) → a single global ticker (`./ticker.ts`)\n * background-refreshes cached entries on a set interval. Stale values keep\n * being served until the fresh value swaps in (bounded staleness, reads\n * never block).\n *\n * Both modes (and any code path that knows better than the streams — e.g. ORM\n * after-write hooks) share one fine-tuned purge primitive: `invalidateIds(collection, ids)`\n * drops exactly the entries depending on those documents; `invalidateCollection`\n * stays the coarse \"drop everything watching this collection\" switch.\n *\n * `start()` resolves the mode once; `stop()` is **terminal** — it tears down\n * the ticker + streams and disposes the instance, so a later `get()` serves\n * cached values read-through without ever re-probing or re-opening background\n * resources. Errors from a loader are never cached, so a transient failure\n * retries on the next read.\n *\n * ## Failure semantics (the staleness window)\n *\n * Freshness is best-effort under failure; the cache keeps serving from memory\n * while the background freshness mechanism is down, so **low latency can hide\n * stale reads**. The guarantees:\n *\n * - **Replica (change streams)** — the watcher self-heals: any stream error or\n * server-side kill (resume-token expiry, rollback, replica failover, dropped\n * collection) closes the stream, retries with jittered backoff (1s → 5s),\n * and **invalidates the bound collection once on reopen**, so entries that\n * could have gone stale during the outage are re-fetched on the next read.\n * Until that reopen happens, cached values are served as-is.\n * - **Standalone (ticker)** — entries are background-refreshed only for\n * queries that set `refreshIntervalMs`; a stale value keeps being served\n * until the fresh value swaps in. Queries with neither `refreshIntervalMs`\n * nor `ttlMs` are served until manually invalidated (unbounded staleness;\n * `start()` logs a warning naming them).\n * - **Bounding the window** — set per-query `ttlMs` and/or `refreshIntervalMs`\n * (or `autoRefresh: false` + manual invalidation) and monitor `stats()` plus\n * the \"change stream reconnected\"/\"change stream error\" warnings to bound how\n * long a stale value can be served.\n *\n * This file is the coordinator: public API + the shared read/fetch pipeline.\n * The two freshness strategies and the size estimator live in sibling modules\n * (`./watcher.ts`, `./ticker.ts`, `./size.ts`) and are injected here, keeping\n * each concern small and independently testable.\n */\nimport { probeMongoCapabilities } from '../../capabilities.ts';\nimport { BadRequest } from '../../errors/index.ts';\nimport { cloneDeep } from '../../utils/clone.ts';\nimport { stableHash } from '../../utils/hash.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { LRU } from '../../utils/lru.ts';\nimport { InFlight } from '../in-flight.ts';\nimport { estimateSize } from './size.ts';\nimport { RefreshTicker } from './ticker.ts';\nimport {\n type Entry,\n type HotCacheMode,\n type HotCacheOptions,\n type HotCacheStats,\n type HotQueryAccessor,\n type HotQueryConfig,\n type HotQueryStats,\n normalizeWatchId,\n type RegisteredQuery,\n resolveWatchDb,\n WATCH_SEP,\n} from './types.ts';\nimport { WatchCoordinator } from './watcher.ts';\n\nexport class HotCache {\n private options: HotCacheOptions;\n private logger: LoggerLike;\n private refreshEnabled: boolean;\n private queries = new Map<string, RegisteredQuery>();\n private inflight = new InFlight();\n private watcher: WatchCoordinator;\n private ticker: RefreshTicker;\n private _mode: HotCacheMode = 'unknown';\n private started = false;\n private startAttempted = false;\n private stopped = false;\n private disposed = false;\n private startPromise: Promise<HotCacheMode> | undefined;\n\n constructor(options: HotCacheOptions = {}) {\n this.options = options;\n this.refreshEnabled = options.autoRefresh !== false;\n this.logger = options.logger ?? { debug() {}, info() {}, warn() {}, error() {} };\n this.ticker = new RefreshTicker(\n {\n queries: () => this.queries,\n fetch: (q, key, args, gen) => this.fetch(q, key, args, gen),\n logger: this.logger,\n },\n options.tickIntervalMs ?? 1000,\n );\n this.watcher = new WatchCoordinator({\n queries: () => this.queries,\n invalidateCollection: (collection) => this.invalidateCollection(collection),\n invalidateDocument: (collection, id) => this.invalidateIds(collection, [id]),\n isReplica: () => this._mode === 'replica',\n fallbackToStandalone: () => {\n this._mode = 'standalone';\n if (this.refreshEnabled && !this.ticker.running) {\n this.ticker.start();\n // Late-registered queries never get the start()-time warning; the\n // fallback path must warn for currently-registered unbounded ones too.\n this.ticker.warnUnboundedStaleness();\n }\n },\n logger: this.logger,\n });\n }\n\n /** Number of cached entries across all registered queries. */\n get size(): number {\n let total = 0;\n for (const q of this.queries.values()) total += q.lru.size;\n return total;\n }\n\n /** Resolved mode: `unknown` until `start()` (or the first `get`) probes. */\n get mode(): HotCacheMode {\n return this._mode;\n }\n\n /** Whether the standalone background-refresh ticker is enabled (`autoRefresh`). */\n get autoRefresh(): boolean {\n return this.refreshEnabled;\n }\n\n /** Whether a query with this name has been registered. */\n has(name: string): boolean {\n return this.queries.has(name);\n }\n\n /**\n * Opt a query into the hot cache. Throws `BadRequest` on a duplicate name.\n * Returns a fully typed accessor — `.get(...args)` (intellisense on the loader\n * parameters) and `.invalidate()` / `.invalidate(...args)` for manual\n * invalidation (all entries or a single parameter set).\n */\n register<TArgs extends readonly unknown[], TResult>(\n name: string,\n config: HotQueryConfig<TArgs, TResult>,\n ): HotQueryAccessor<TArgs, TResult> {\n if (this.queries.has(name)) {\n throw new BadRequest(`hot cache: query '${name}' is already registered`);\n }\n const query: RegisteredQuery = {\n name,\n config: config as HotQueryConfig<readonly unknown[], unknown>,\n lru: new LRU<string, Entry>({\n max: config.maxSize ?? this.options.defaultMaxSize ?? 500,\n }),\n ttlMs: config.ttlMs ?? this.options.defaultTtlMs ?? 0,\n refreshIntervalMs: config.refreshIntervalMs ?? 0,\n clone: config.clone ?? false,\n ...(config.maxValueBytes !== undefined ? { maxValueBytes: config.maxValueBytes } : {}),\n hasIdWatch: (config.watch ?? []).some((ref) => typeof ref.idsOf === 'function'),\n gen: 0,\n hits: 0,\n misses: 0,\n refreshes: 0,\n loadErrors: 0,\n sizeSkips: 0,\n idDrops: 0,\n warnedSize: false,\n };\n this.queries.set(name, query);\n // If already running in replica mode, wire change streams for new watch refs.\n if (this._mode === 'replica' && !this.stopped) {\n this.watcher.start();\n }\n // Named consts (not inline arrows) so stack frames read `get`/`invalidate`\n // instead of `<anonymous>` when user code goes through the accessor.\n const get = (...args: TArgs): Promise<TResult> => this.get(name, ...args) as Promise<TResult>;\n const invalidate = (...args: TArgs): void => {\n if (args.length === 0) this.invalidate(name);\n else this.invalidateParams(name, ...args);\n };\n return { get, invalidate };\n }\n\n /**\n * Read-through read by dynamic name lookup. Call parameters are hashed into\n * the cache key (`keyOf` override wins). Throws `BadRequest` for an unknown\n * query name. For fully typed parameters/results prefer the accessor returned\n * by `register()` — this dynamic form returns `Promise<unknown>`.\n */\n async get(name: string, ...args: unknown[]): Promise<unknown> {\n this.ensureStarted();\n const q = this.queries.get(name);\n if (!q) throw new BadRequest(`hot cache: unknown query '${name}'`);\n const key = q.config.keyOf ? q.config.keyOf(...args) : stableHash(args);\n const entry = q.lru.get(key);\n if (entry && !(q.ttlMs > 0 && entry.expiresAt <= Date.now())) {\n q.hits++;\n // Each read gets its own copy so the stored entry can't be mutated.\n return q.clone ? cloneDeep(entry.value) : entry.value;\n }\n if (entry && q.ttlMs > 0 && entry.expiresAt <= Date.now()) {\n // Drop the dead entry eagerly so `size`/`stats()` stay accurate.\n q.lru.delete(key);\n }\n q.misses++;\n // `await` (not a bare `return`): a non-awaited return from an async\n // function unwinds the caller chain in Bun's stack capture, so the ignex\n // debugbar's span origin would truncate here and never reach the route\n // handler that issued this read.\n return await this.fetch(q, key, args, q.gen);\n }\n\n /** Drop every cached entry for a registered query. */\n invalidate(name: string): void {\n const q = this.queries.get(name);\n if (!q) return;\n q.lru.clear();\n q.gen++;\n }\n\n /**\n * Drop only the cached entry for a specific parameter set. The key is computed\n * exactly like `get` (`keyOf` override ?? `stableHash` of args), so the same\n * parameters invalidate the same entry.\n */\n invalidateParams(name: string, ...args: unknown[]): void {\n const q = this.queries.get(name);\n if (!q) return;\n const key = q.config.keyOf ? q.config.keyOf(...args) : stableHash(args);\n q.lru.delete(key);\n q.gen++;\n }\n\n /**\n * Invalidate every query bound to a physical collection (via `watch`). Can be\n * called manually to wire ORM write hooks in standalone mode.\n */\n invalidateCollection(collection: string): void {\n for (const q of this.queries.values()) {\n if (q.config.watch?.some((ref) => ref.collection === collection)) {\n q.lru.clear();\n q.gen++;\n }\n }\n }\n\n /**\n * Fine-tuned purge: drop only the entries that depend on specific document\n * ids of a watched collection. Two complementary mechanisms feed it:\n *\n * - **Replica mode** — the change stream extracts `documentKey._id` from\n * each event and calls this with just that id, so a write to one document\n * no longer purges every query bound to the whole collection.\n * - **Manual (any mode)** — call it from ORM after-write hooks or anywhere\n * else you know exactly which ids changed.\n *\n * Per query bound to `collection`, semantics are:\n * - watch ref declares `idsOf` → only LRU entries whose extracted ids\n * include one of `ids` are dropped (`depsAll` entries — where extraction\n * failed — are dropped too; conservative). Sibling entries stay warm and\n * `stats().perQuery[name].idDrops` counts what was dropped.\n * - no `idsOf` on any bound ref → full purge of that query (the\n * `invalidateCollection` behavior — the safe default).\n */\n invalidateIds(collection: string, ids: readonly unknown[]): void {\n if (ids.length === 0) return;\n // Deps are stored namespaced (`${collection}${WATCH_SEP}${id}`) so\n // multi-collection watchers never cross-invalidate — match that exact shape.\n const changed = new Set<string>();\n for (const id of ids) changed.add(`${collection}${WATCH_SEP}${normalizeWatchId(id)}`);\n for (const q of this.queries.values()) {\n const bound = q.config.watch?.filter((ref) => ref.collection === collection);\n if (!bound || bound.length === 0) continue;\n if (!bound.some((ref) => typeof ref.idsOf === 'function')) {\n // No id-level extractor for this collection → keep the coarse contract.\n q.lru.clear();\n q.gen++;\n continue;\n }\n let dropped = 0;\n for (const [key, entry] of [...q.lru.entries()]) {\n const matches =\n entry.depsAll === true || entry.deps?.some((dep) => changed.has(dep)) === true;\n if (matches) {\n q.lru.delete(key);\n dropped++;\n }\n }\n q.idDrops += dropped;\n // Unconditional race guard (even when nothing was dropped): an in-flight\n // load for these args must never re-store a value fetched BEFORE the\n // change event — otherwise a change landing mid-load would pin the old\n // value in the cache with no TTL to rescue it.\n q.gen++;\n }\n }\n\n /** Drop every cached entry for every query. */\n clear(): void {\n for (const q of this.queries.values()) {\n q.lru.clear();\n q.gen++;\n }\n }\n\n /**\n * Runtime observability snapshot: total queries/entries plus per-query\n * counters (`hits`, `misses`, background `refreshes`, `loadErrors`,\n * `sizeSkips` for entries dropped by `maxValueBytes`, and `idDrops` for\n * entries dropped by id-targeted invalidation). Useful for dashboards and\n * cache-effectiveness checks.\n */\n stats(): HotCacheStats {\n const perQuery: Record<string, HotQueryStats> = {};\n for (const [name, q] of this.queries) {\n perQuery[name] = {\n size: q.lru.size,\n hits: q.hits,\n misses: q.misses,\n refreshes: q.refreshes,\n loadErrors: q.loadErrors,\n sizeSkips: q.sizeSkips,\n idDrops: q.idDrops,\n evictions: q.lru.evictions,\n };\n }\n return { mode: this._mode, queries: this.queries.size, entries: this.size, perQuery };\n }\n\n /**\n * Probe replica support once, then start change-stream watchers (replica) or\n * the global refresh ticker (standalone). Idempotent — resolves the mode.\n * A FAILED start does not stick: the memoized promise is cleared so the next\n * `get()`/`start()` retries probing (one transient blip during startup must\n * not disable background freshness for the life of the instance).\n */\n async start(): Promise<HotCacheMode> {\n if (this.disposed) return this._mode;\n if (this.started) return this._mode;\n if (!this.startPromise) {\n this.startPromise = this.runStart().catch(this.forgetFailedStart);\n }\n return this.startPromise;\n }\n\n /**\n * Stop the ticker, close every change stream, and **dispose** the instance.\n * Terminal: a later `get()` serves cached values read-through but never\n * re-probes or re-opens background resources.\n */\n async stop(): Promise<void> {\n this.disposed = true;\n this.stopped = true;\n this.ticker.stop();\n await this.watcher.stop();\n this.inflight.clear();\n // In-flight loads shouldn't re-populate the cache during/after teardown.\n for (const q of this.queries.values()) q.gen++;\n this.started = false;\n this.startAttempted = false;\n this.startPromise = undefined;\n this._mode = 'unknown';\n }\n\n /* ----------------------------- internals ----------------------------- */\n\n /**\n * A FAILED start does not stick: clear the memoized state so the next\n * `get()`/`start()` retries probing (one transient blip during startup must\n * not disable background freshness for the life of the instance).\n */\n private forgetFailedStart = (err: unknown): never => {\n this.startPromise = undefined;\n this.startAttempted = false;\n this.started = false;\n throw err;\n };\n\n private async runStart(): Promise<HotCacheMode> {\n this.stopped = false;\n const supported =\n this.options.mode === 'replica'\n ? true\n : this.options.mode === 'standalone'\n ? false\n : await (this.options.probe ?? this.defaultProbe)();\n // stop() may have run while the probe was in flight — don't re-open resources.\n if (this.disposed) {\n this.started = false;\n return this._mode;\n }\n if (supported) {\n this._mode = 'replica';\n this.watcher.start();\n } else {\n this._mode = 'standalone';\n if (this.refreshEnabled) {\n this.ticker.start();\n this.ticker.warnUnboundedStaleness();\n }\n }\n this.started = true;\n return this._mode;\n }\n\n private ensureStarted(): void {\n if (this.disposed || this.started || this.startAttempted) return;\n this.startAttempted = true;\n // Fire-and-forget: the rejection crosses a promise boundary, so the error's\n // own stack will NOT contain whoever triggered this read. Snapshot the\n // synchronous caller chain NOW and attach it as `cause` + log meta —\n // otherwise \"start failed\" warnings are unattributable.\n const origin = new Error('hot cache: background start() was triggered by this call');\n const reportStartFailure = (err: unknown): void => {\n const wrapped = err instanceof Error ? err : new Error(String(err));\n if (wrapped.cause === undefined) wrapped.cause = origin;\n this.logger.warn?.(\n { error: wrapped.message, stack: wrapped.stack, trigger: origin.stack },\n 'hot cache start failed; reads continue without auto-refresh',\n );\n };\n this.start().catch(reportStartFailure);\n }\n\n private defaultProbe = async (): Promise<boolean> => {\n for (const q of this.queries.values()) {\n for (const ref of q.config.watch ?? []) {\n let db: { databaseName: string };\n try {\n db = resolveWatchDb(ref);\n } catch {\n // Lazy accessor not ready (module-scope registration before connect)\n // — treat as \"unknown\", not standalone.\n this.logger.warn?.(\n {},\n 'hot cache: replica probe could not resolve the watch db (accessor threw) — falling back to the standalone ticker; pass `mode` or a custom `probe` to pin the behavior',\n );\n return false;\n }\n const caps = await probeMongoCapabilities(db as never);\n if (!caps.probed) {\n // A timed-out/failed probe is NOT \"confirmed standalone\" — falling back\n // to the ticker silently could surprise replica users. Warn loudly so\n // they can pin the behavior with `mode` or a custom `probe`.\n this.logger.warn?.(\n { db: db.databaseName },\n 'hot cache: replica probe returned no result (timeout?) — falling back to the standalone ticker; pass `mode` or a custom `probe` to pin the behavior',\n );\n return false;\n }\n return caps.transactionsSupported;\n }\n }\n return false;\n };\n\n private fetch(\n q: RegisteredQuery,\n key: string,\n args: readonly unknown[],\n gen: number,\n ): Promise<unknown> {\n // The generation is part of the dedup identity: a reader arriving AFTER an\n // invalidation must start a FRESH load, never join the pre-invalidation\n // in-flight one (whose result is stale-by-arrival for it).\n const dedupeKey = `${q.name}${WATCH_SEP}g${gen}${WATCH_SEP}${key}`;\n // Named const (not an inline async arrow) so loader frames read `loadOnce`\n // instead of `<anonymous>` in error stacks.\n const loadOnce = async (): Promise<unknown> => {\n try {\n const value = await q.config.loader(...args);\n // Generation guard: if an invalidation/clear happened while the loader\n // was in flight, the result is stale-by-arrival — don't re-store it.\n // The caller still receives the value; the next read re-fetches.\n if (q.gen === gen) {\n const bytes = q.maxValueBytes !== undefined ? estimateSize(value) : undefined;\n if (bytes !== undefined && bytes > q.maxValueBytes!) {\n q.sizeSkips++;\n if (!q.warnedSize) {\n q.warnedSize = true;\n this.logger.warn?.(\n { query: q.name, bytes, max: q.maxValueBytes },\n 'hot cache: value exceeds maxValueBytes — returned but not cached',\n );\n }\n } else {\n this.setEntry(q, key, args, value);\n }\n }\n return value;\n } catch (err) {\n q.loadErrors++;\n throw err;\n }\n };\n return this.inflight.run<unknown>(dedupeKey, loadOnce);\n }\n\n private setEntry(\n q: RegisteredQuery,\n key: string,\n args: readonly unknown[],\n value: unknown,\n ): void {\n const now = Date.now();\n // Id-level watch: record which watched documents this result depends on, so\n // `invalidateIds` (change stream or manual) can purge exactly these entries.\n const deps = q.hasIdWatch ? this.computeDeps(q, args) : {};\n q.lru.set(key, {\n value,\n args,\n expiresAt: q.ttlMs > 0 ? now + q.ttlMs : Infinity,\n nextRefreshAt: q.refreshIntervalMs > 0 ? now + q.refreshIntervalMs : Infinity,\n ...deps,\n });\n }\n\n /**\n * Extract the watched-document dependencies of one loader call. Namespaced by\n * collection so multi-collection watchers never cross-invalidate. An extractor\n * that throws or returns a non-array yields `{ depsAll: true }` — the entry is\n * then dropped by ANY targeted change on its watched collections instead of\n * being incorrectly kept.\n */\n private computeDeps(\n q: RegisteredQuery,\n args: readonly unknown[],\n ): Pick<Entry, 'deps' | 'depsAll'> {\n const deps: string[] = [];\n for (const ref of q.config.watch ?? []) {\n if (!ref.idsOf) continue;\n // The `never`-params declaration is contravariance-safe for writers; the\n // runtime contract is that it accepts the loader's argument tuple.\n const extract = ref.idsOf as (...args: readonly unknown[]) => readonly unknown[];\n try {\n const ids = extract(...args);\n if (!Array.isArray(ids)) return { depsAll: true };\n for (const id of ids) deps.push(`${ref.collection}${WATCH_SEP}${normalizeWatchId(id)}`);\n } catch {\n return { depsAll: true };\n }\n }\n return { deps };\n }\n}\n\n/** Create a new global hot-cache instance. */\nexport const createHotCache = (options?: HotCacheOptions): HotCache => new HotCache(options);\n\n// Re-export the public HotCache types so the folder barrel matches the old\n// single-module exports.\nexport type {\n Entry,\n HotCacheMode,\n HotCacheOptions,\n HotCacheStats,\n HotCollectionRef,\n HotQueryAccessor,\n HotQueryConfig,\n HotQueryStats,\n RegisteredQuery,\n} from './types.ts';\n","import { cloneDeep } from '../utils/clone.ts';\nimport { LRU } from '../utils/lru.ts';\n\nexport interface QueryCacheOptions {\n /** Max cached entries (default 500). */\n maxSize?: number;\n /** Per-entry TTL in ms (default 0 = no expiry). */\n ttlMs?: number;\n /**\n * Clone results on every read so callers can't mutate the shared cache entry\n * (default false — cloning has a per-read cost; treat cached results as\n * read-only when disabled).\n */\n clone?: boolean;\n}\n\ninterface Entry<V> {\n value: V;\n expiresAt: number;\n /**\n * Per-source-collection version at READ start (see `versionOf`). When an\n * invalidation bumps a collection's version while a read is in-flight, the\n * stored version no longer matches and `get()` treats the entry as stale —\n * this is the write-after-invalidate race guard (mirrors HotCache's `gen`).\n */\n versions?: Record<string, number>;\n}\n\n/** Snapshot of cache health (see `QueryCache.stats()`). */\nexport interface QueryCacheStats {\n size: number;\n maxSize: number;\n /** Reads served from the cache without touching the DB. */\n hits: number;\n /** Reads that missed (absent or expired). */\n misses: number;\n /** `set()` calls (writes to the cache). */\n sets: number;\n /** `delete()` calls. */\n deletes: number;\n /** `invalidateByCollection` calls that actually dropped entries. */\n invalidateEvents: number;\n /** `clear()` calls. */\n clearEvents: number;\n /** Capacity evictions (LRU). */\n evictions: number;\n}\n\nconst SEP = '\\u0000';\n/** Namespace separator between the database name and physical collection. */\nconst NS_SEP = '\\u0001';\n\n/**\n * Compose the \"collection\" part of a cache key, namespaced by the DATABASE name.\n * One service shares a single QueryCache + InFlight across every DB client; without\n * the namespace, same-named physical collections in different databases would\n * collide — a read on DB A could be served DB B's cached rows, and identical\n * concurrent reads across DBs could coalesce into one driver call. Reads,\n * write-through invalidations, and change-stream invalidations MUST all use the\n * same namespace so they agree.\n */\nexport const cacheCollectionKey = (dbName: string, physical: string): string =>\n `${dbName}${NS_SEP}${physical}`;\n\n/**\n * Read-through query cache with per-collection invalidation.\n *\n * Keys are `collection<sep>hash` so a single write can invalidate every cached\n * read for that collection. `set()` can also register an entry under ADDITIONAL\n * collection keys (see `collections`) so derived reads — e.g. an aggregation\n * with `$lookup`/`$unionWith` — are invalidated when ANY of their source\n * collections changes. Invalidation is WRITE-THROUGH only: the ORM drops a\n * collection's entries on every write it performs. Reads are NOT invalidated by\n * external writers (other processes, the raw `client` escape hatch, or direct\n * DB writes) — with `ttlMs: 0` (default) those reads stay stale indefinitely,\n * so multi-writer deployments should set `ttlMs` or use the change-stream aware\n * `createHotCache()`. Perf wins: cache hits perform zero driver round-trips.\n */\nexport class QueryCache {\n private lru: LRU<string, Entry<unknown>>;\n private index = new Map<string, Set<string>>();\n /**\n * Reverse index: key → every collection it is registered under. Without it,\n * keys dropped by TTL expiry / capacity eviction / version-guard would stay\n * listed in `index` forever (unbounded growth + O(dead) invalidation scans).\n */\n private keyCollections = new Map<string, Set<string>>();\n /** Per-collection version — bumped on every invalidation/clear of that collection. */\n private colVersions = new Map<string, number>();\n private ttlMs: number;\n private clone: boolean;\n private hits = 0;\n private misses = 0;\n private sets = 0;\n private deletes = 0;\n private invalidateEvents = 0;\n private clearEvents = 0;\n\n constructor(options: QueryCacheOptions = {}) {\n this.lru = new LRU<string, Entry<unknown>>({\n max: options.maxSize ?? 500,\n onEvict: (key) => this.unregisterKey(key),\n });\n this.ttlMs = options.ttlMs ?? 0;\n this.clone = options.clone ?? false;\n }\n\n get size(): number {\n return this.lru.size;\n }\n\n /** Cache-health snapshot: sizes plus lifetime hit/miss/eviction counters. */\n stats(): QueryCacheStats {\n return {\n size: this.lru.size,\n maxSize: this.lru.max,\n hits: this.hits,\n misses: this.misses,\n sets: this.sets,\n deletes: this.deletes,\n invalidateEvents: this.invalidateEvents,\n clearEvents: this.clearEvents,\n evictions: this.lru.evictions,\n };\n }\n\n /** Compose a cache key for a collection + filter/options hash. */\n key(collection: string, filterHash: string): string {\n return `${collection}${SEP}${filterHash}`;\n }\n\n /**\n * Current version of a collection key (db-namespaced, e.g. from\n * `cacheCollectionKey`). Reads capture it BEFORE fetching and pass it to\n * `set()` so a concurrent invalidation can never be hidden by a late write.\n */\n versionOf(collection: string): number {\n return this.colVersions.get(collection) ?? 0;\n }\n\n get(key: string): unknown | undefined {\n const entry = this.lru.get(key);\n if (!entry) {\n this.misses++;\n return undefined;\n }\n if (this.ttlMs > 0 && Date.now() > entry.expiresAt) {\n this.dropKey(key);\n this.misses++;\n return undefined;\n }\n // Write-after-invalidate guard: if any source collection was invalidated\n // after this entry was computed (its stored version lags the current one),\n // the value is stale-by-arrival — drop it and force a re-fetch.\n if (entry.versions) {\n for (const [col, ver] of Object.entries(entry.versions)) {\n if (this.versionOf(col) !== ver) {\n this.dropKey(key);\n this.misses++;\n return undefined;\n }\n }\n }\n this.hits++;\n // Each read gets its own copy so the stored entry can't be mutated.\n return this.clone ? cloneDeep(entry.value) : entry.value;\n }\n\n /** Remove a key from the LRU and every collection index that references it. */\n private dropKey(key: string): void {\n this.lru.delete(key);\n this.unregisterKey(key);\n }\n\n /** Remove `key` from `index` (called for evictions AND explicit drops). */\n private unregisterKey(key: string): void {\n const collections = this.keyCollections.get(key);\n if (!collections) return;\n this.keyCollections.delete(key);\n for (const collection of collections) {\n const keys = this.index.get(collection);\n if (!keys) continue;\n keys.delete(key);\n if (keys.size === 0) this.index.delete(collection);\n }\n }\n\n set(\n key: string,\n value: unknown,\n ttlMs?: number,\n collections?: string[],\n versions?: Record<string, number>,\n ): void {\n this.sets++;\n const ttl = ttlMs ?? this.ttlMs;\n const expiresAt = ttl > 0 ? Date.now() + ttl : Infinity;\n this.lru.set(key, {\n value,\n expiresAt,\n ...(versions !== undefined ? { versions } : {}),\n });\n // Primary collection is derived from the key prefix. `collections` lists\n // ADDITIONAL source collections the entry depends on (e.g. the `$lookup`\n // join target of a cached aggregation) — registering the key under each\n // means a write to ANY source drops the entry. The reverse index keeps\n // both sides in sync so evictions/expiry never leak dead references.\n const sep = key.indexOf(SEP);\n const primary = sep === -1 ? key : key.slice(0, sep);\n const collectionKeys = new Set<string>([primary, ...(collections ?? [])]);\n this.keyCollections.set(key, collectionKeys);\n for (const collection of collectionKeys) {\n let keys = this.index.get(collection);\n if (!keys) {\n keys = new Set<string>();\n this.index.set(collection, keys);\n }\n keys.add(key);\n }\n }\n\n delete(key: string): void {\n this.deletes++;\n this.dropKey(key);\n }\n\n /** Drop every cached entry belonging to a physical collection. */\n invalidateByCollection(collection: string): void {\n // Bump the collection version BEFORE dropping, so any in-flight read that\n // started earlier can never re-store a stale value (see `get` guard).\n this.colVersions.set(collection, (this.colVersions.get(collection) ?? 0) + 1);\n const keys = this.index.get(collection);\n if (!keys) return;\n this.invalidateEvents++;\n // dropKey also unregisters each key from its OTHER source collections\n // (e.g. a `$lookup` entry listed under both sides) — no dead refs left.\n for (const key of [...keys]) this.dropKey(key);\n this.index.delete(collection);\n }\n\n clear(): void {\n this.clearEvents++;\n // Bump every known collection so in-flight reads can't re-store stale\n // values past a clear() either.\n for (const collection of this.index.keys()) {\n this.colVersions.set(collection, (this.colVersions.get(collection) ?? 0) + 1);\n }\n this.lru.clear();\n this.index.clear();\n this.keyCollections.clear();\n }\n}\n","import type { ClientSession } from 'mongodb';\nimport {\n type createMongoCapabilitiesStore,\n readMongoTransactionsEnvOverride,\n} from './capabilities.ts';\nimport { isTransactionUnsupportedError, mapMongoDriverError } from './errors/index.ts';\nimport type { LoggerLike } from './utils/logger.ts';\n\n/** Minimal transaction runner surface (satisfied by the service `transaction`). */\nexport interface MongoTransactionRunner {\n transaction: <T>(fn: (session: ClientSession | null) => Promise<T>) => Promise<T>;\n}\n\nexport interface GracefulTransactionOptions {\n capabilities?: ReturnType<typeof createMongoCapabilitiesStore>;\n urlHint?: string;\n logger?: LoggerLike;\n /** Map driver errors to typed DomainError/InfraError before rethrowing (default true). */\n wrapMongoErrors?: boolean;\n}\n\n/**\n * Run `fn` inside a transaction when the deployment supports it; otherwise run\n * with a `null` session (no-op fallback). Also handles \"transactions\n * unsupported\" errors by re-running with a null session.\n *\n * When capability state is UNKNOWN (probe failed/timed out and no URL hint or\n * env override says otherwise), we ATTEMPT the real transaction rather than\n * silently downgrading — a transient startup blip must not turn an atomic\n * write into a non-atomic one. The catch path still falls back cleanly on a\n * genuinely unsupported deployment (at the cost of one failed round trip).\n */\nexport const withGracefulMongoTransaction = async <T>(\n runner: MongoTransactionRunner,\n fn: (session: ClientSession | null) => Promise<T>,\n options: GracefulTransactionOptions = {},\n): Promise<T> => {\n let enabled = true;\n if (options.capabilities !== undefined) {\n const env = readMongoTransactionsEnvOverride();\n if (env !== undefined) {\n enabled = env;\n } else {\n const state = options.capabilities.get();\n if (state.probed) {\n enabled = state.transactionsSupported;\n } else if (options.urlHint) {\n enabled = /replicaSet=|mongodb\\+srv:/i.test(options.urlHint);\n } // else UNKNOWN → keep `true` and let the attempt/fallback decide.\n }\n }\n if (!enabled) return fn(null);\n\n try {\n return await runner.transaction(fn);\n } catch (err) {\n if (isTransactionUnsupportedError(err)) {\n options.logger?.warn?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'transactions unsupported, falling back',\n );\n return fn(null);\n }\n if (options.wrapMongoErrors !== false) {\n throw mapMongoDriverError(err, { op: 'transaction' });\n }\n throw err;\n }\n};\n","import type { Document, Filter } from 'mongodb';\n\n/**\n * Lifecycle hooks — the ORM's middleware system. Hooks are declared per\n * collection and run around the corresponding CRUD operation.\n */\nexport type HookName =\n | 'beforeCreate'\n | 'afterCreate'\n | 'beforeUpdate'\n | 'afterUpdate'\n | 'beforeDelete'\n | 'afterDelete'\n | 'afterRead';\n\nexport interface HookContext<TSchema = Document> {\n collection: string;\n doc?: TSchema;\n docs?: TSchema[];\n filter?: Filter<Document>;\n options?: Record<string, unknown>;\n}\n\nexport type Hook<TSchema = Document> = (ctx: HookContext<TSchema>) => void | Promise<void>;\n\nexport type HookMap<TSchema = Document> = Partial<Record<HookName, Hook<TSchema>>>;\n\n/** Registry keyed by logical collection name. */\nexport type HooksRegistry = Record<string, HookMap>;\n\nexport const HOOK_NAMES: readonly HookName[] = [\n 'beforeCreate',\n 'afterCreate',\n 'beforeUpdate',\n 'afterUpdate',\n 'beforeDelete',\n 'afterDelete',\n 'afterRead',\n];\n\n/** True when a hook is registered for the given collection + name. */\nexport const hasHook = (\n registry: HooksRegistry | undefined,\n collection: string,\n name: HookName,\n): boolean => registry?.[collection]?.[name] !== undefined;\n\n/** Run a single hook (no-op when the collection has none registered). */\nexport const runHooks = async <TSchema = Document>(\n registry: HooksRegistry | undefined,\n collection: string,\n name: HookName,\n ctx: HookContext<TSchema>,\n): Promise<void> => {\n const hooks = registry?.[collection];\n const hook = hooks?.[name];\n if (!hook) return;\n await hook(ctx as HookContext<Document>);\n};\n","/**\n * A self-contained DataLoader — batch + cache loading that eliminates the\n * N+1 query problem (the classic GraphQL utility, implemented from scratch so\n * the ORM owns its batching behavior).\n *\n * Semantics:\n * - concurrent `load(key)` calls made in the same tick are coalesced into ONE\n * `batch(keys)` call (flushed on a microtask, or after `maxBatchDelayMs`)\n * - the batch result is a Map (key → value); a missing key resolves `undefined`\n * - results are cached per key (canonicalized via `keyOf`) for the loader's\n * lifetime; `clear`/`clearAll` reset the cache\n * - a FAILED batch is never cached: its keys are evicted so a later `load`\n * runs a fresh batch instead of re-surfacing the same rejection\n * - `maxBatchSize` splits oversized batches\n */\nimport { stableStringify } from '../utils/hash.ts';\n\nexport interface DataLoaderOptions<Key, Value> {\n /** Resolve a batch of keys → one Map. Keys that have no row should be absent. */\n batch: (keys: Key[]) => Promise<Map<Key, Value>>;\n /** Max keys per batch call (default 1000). */\n maxBatchSize?: number;\n /** Flush delay in ms (default 0 → microtask flush, i.e. one tick batching). */\n maxBatchDelayMs?: number;\n /** Cache loaded values (default true). */\n cache?: boolean;\n /** Canonical key function for value-based keys (ObjectId, Date, ...). */\n keyOf?: (key: Key) => string;\n cacheMap?: Map<string, Promise<Value | undefined>>;\n}\n\ninterface QueueItem<Key, Value> {\n key: Key;\n canonicalKey: string;\n /** The promise returned to the caller — kept so a failed batch can evict exactly this cache entry. */\n promise: Promise<Value | undefined>;\n resolve: (value: Value | undefined) => void;\n reject: (error: unknown) => void;\n}\n\nexport class DataLoader<Key, Value> {\n private readonly batchFn: (keys: Key[]) => Promise<Map<Key, Value>>;\n private readonly maxBatchSize: number;\n private readonly maxBatchDelayMs: number;\n private readonly cacheEnabled: boolean;\n private readonly keyOf: (key: Key) => string;\n private readonly cache: Map<string, Promise<Value | undefined>>;\n\n private queue: Array<QueueItem<Key, Value>> = [];\n private scheduled = false;\n private flushing = false;\n\n constructor(options: DataLoaderOptions<Key, Value>) {\n this.batchFn = options.batch;\n this.maxBatchSize = options.maxBatchSize ?? 1000;\n this.maxBatchDelayMs = options.maxBatchDelayMs ?? 0;\n this.cacheEnabled = options.cache ?? true;\n this.keyOf = options.keyOf ?? ((key: Key): string => `${typeof key}:${String(key)}`);\n this.cache = options.cacheMap ?? new Map();\n }\n\n /** Load one key. Concurrent loads are batched; cached keys resolve instantly. */\n load(key: Key): Promise<Value | undefined> {\n const canonicalKey = this.keyOf(key);\n if (this.cacheEnabled) {\n const cached = this.cache.get(canonicalKey);\n if (cached) return cached;\n }\n\n let resolve!: (value: Value | undefined) => void;\n let reject!: (error: unknown) => void;\n const promise = new Promise<Value | undefined>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n this.queue.push({ key, canonicalKey, promise, resolve, reject });\n if (this.cacheEnabled) this.cache.set(canonicalKey, promise);\n\n this.scheduleFlush();\n return promise;\n }\n\n /** Load many keys (each resolves independently). */\n loadMany(keys: readonly Key[]): Promise<Array<Value | undefined>> {\n return Promise.all(keys.map((key) => this.load(key)));\n }\n\n clear(key: Key): this {\n this.cache.delete(this.keyOf(key));\n return this;\n }\n\n clearAll(): this {\n this.cache.clear();\n return this;\n }\n\n /** Pre-populate the cache without hitting the batch function. */\n prime(key: Key, value: Value): this {\n if (this.cacheEnabled) this.cache.set(this.keyOf(key), Promise.resolve(value));\n return this;\n }\n\n get pendingCount(): number {\n return this.queue.length;\n }\n\n private scheduleFlush(): void {\n if (this.scheduled) return;\n this.scheduled = true;\n if (this.maxBatchDelayMs > 0) {\n setTimeout(() => {\n void this.flush();\n }, this.maxBatchDelayMs);\n } else {\n queueMicrotask(() => {\n void this.flush();\n });\n }\n }\n\n private async flush(): Promise<void> {\n if (this.flushing) {\n // A flush is already running and drained the queue slice; reset the\n // flag so its `finally` re-schedules us for the leftover items.\n this.scheduled = false;\n return;\n }\n if (this.queue.length === 0) {\n this.scheduled = false;\n return;\n }\n\n const items = this.queue.splice(0, this.maxBatchSize);\n this.flushing = true;\n // Re-open the scheduling window BEFORE the batch runs: loads arriving\n // mid-flight then open a fresh `maxBatchDelayMs` window instead of never\n // being scheduled (the old code kept `scheduled` true for the whole\n // batch, collapsing the configured coalescing window after the first one).\n this.scheduled = false;\n try {\n const resultMap = await this.batchFn(items.map((item) => item.key));\n for (const item of items) {\n item.resolve(resultMap.get(item.key));\n }\n } catch (error) {\n for (const item of items) {\n // Never cache a failure: evict this exact promise (guarded by identity\n // so a newer load of the same key created mid-batch is left intact),\n // then reject — a later load will run a fresh batch.\n if (this.cacheEnabled && this.cache.get(item.canonicalKey) === item.promise) {\n this.cache.delete(item.canonicalKey);\n }\n item.reject(error);\n }\n } finally {\n this.flushing = false;\n // Leftover keys (maxBatchSize split / arrivals during the batch) go\n // through the normal scheduler so they honor the configured window.\n if (!this.scheduled && this.queue.length > 0) {\n this.scheduleFlush();\n }\n }\n }\n}\n\n/** Canonical key for value-comparison keys (ObjectId → hex, primitives → typed string). */\nexport const canonicalKey = (value: unknown): string => {\n if (value === undefined || value === null) return 'null';\n if (typeof value === 'object') {\n const anyValue = value as { toHexString?: () => string };\n if (typeof anyValue.toHexString === 'function') return `oid:${anyValue.toHexString()}`;\n if (value instanceof Date) return `date:${value.getTime()}`;\n // Plain objects: deterministic serialization — `String(value)` collapsed\n // every object to \"[object Object]\", making distinct keys collide.\n return `obj:${stableStringify(value)}`;\n }\n return `${typeof value}:${String(value)}`;\n};\n","/**\n * Migration types + constants shared by `./files.ts` (discovery/scaffolding),\n * `./journal.ts` (the `_migrations` journal) and `./index.ts` (the runner).\n */\nimport type { Document } from 'mongodb';\nimport type { LoggerLike } from '../utils/logger.ts';\n\nexport interface MigrationContext {\n service: unknown;\n logger: LoggerLike;\n name: string;\n}\n\nexport interface MigrationModule {\n up: (ctx: MigrationContext) => void | Promise<void>;\n down: (ctx: MigrationContext) => void | Promise<void>;\n}\n\n/** Minimal manager surface the journaling uses (satisfied by `service.db.*Client`). */\nexport interface JournalManager {\n insertOne(collection: string, doc: Document): Promise<unknown>;\n findMany(collection: string, filter?: Document): Promise<Document[]>;\n deleteOne(collection: string, filter: Document): Promise<unknown>;\n deleteMany(collection: string, filter: Document): Promise<unknown>;\n updateOne(\n collection: string,\n filter: Document,\n update: Document,\n ): Promise<{ matchedCount?: number } | unknown>;\n findOneAndUpdate(\n collection: string,\n filter: Document,\n update: Document,\n options?: Record<string, unknown>,\n ): Promise<Document | null>;\n /** Optional — used to enforce journal-row uniqueness across runners. */\n createIndex?(\n collection: string,\n key: Document,\n options?: Record<string, unknown>,\n ): Promise<unknown>;\n}\n\nexport interface MongoMigrationRunner {\n /** Apply every not-yet-applied migration in numeric order. */\n up(): Promise<void>;\n /**\n * Roll back applied migrations in reverse order (down to `targetName` when\n * given). An unknown `targetName` throws BEFORE anything is rolled back.\n */\n down(targetName?: string): Promise<void>;\n status(): Promise<{ applied: string[]; pending: string[] }>;\n /** Scaffold a new `NNN_name.ts` migration file; returns its path. */\n create(name: string): Promise<string>;\n}\n\nexport interface MongoMigrationRunnerOptions {\n migrationDir?: string;\n logger?: LoggerLike;\n /**\n * Which connected database the journal + migrations target (key of the\n * service's db map). Defaults to the FIRST connected key — set this explicitly\n * in multi-database services to avoid silently migrating the wrong one.\n */\n db?: string;\n /**\n * Migration claim lease in ms (default 120_000). A `running` claim older than\n * the lease is considered orphaned (hard crash) and may be stolen by another\n * runner; live claims are renewed automatically during long `up()`s.\n */\n leaseMs?: number;\n}\n\n/** Matches `NNN_name.ts|js|mjs` — the numeric prefix drives ordering. */\nexport const MIGRATION_FILE = /^(\\d+)_.+\\.(ts|js|mjs)$/;\n\n/** Collection name of the migration journal (reserved `_`-prefixed name). */\nexport const JOURNAL_COLLECTION = '_migrations';\n","/**\n * Migration file discovery + loading + scaffolding (pure filesystem helpers).\n * `listMigrationFiles` orders by the numeric prefix; `loadMigration` imports a\n * file as a module; `nextMigrationNumber`/`ensureDir` support `create`.\n */\nimport { mkdir, readdir } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { MIGRATION_FILE, type MigrationModule } from './types.ts';\n\n/** Strip the `NNN_` prefix and extension → the migration's logical name. */\nexport const migrationNameOf = (file: string): string =>\n basename(file).replace(/\\.(ts|js|mjs)$/, '');\n\nconst numericPrefixOf = (file: string): number =>\n Number(MIGRATION_FILE.exec(basename(file))?.[1] ?? Number.MAX_SAFE_INTEGER);\n\n/**\n * List migration files ordered by NUMERIC prefix (then name). A plain string\n * sort would run `1000_late.ts` before `999_early.ts` and `45_x.ts` after\n * `100_y.ts` — silently reordering schema evolution.\n */\nexport const listMigrationFiles = async (dir: string): Promise<string[]> => {\n const files = await readdir(dir);\n return files\n .filter((file) => MIGRATION_FILE.test(file))\n .sort((a, b) => numericPrefixOf(a) - numericPrefixOf(b) || a.localeCompare(b));\n};\n\n/** Import a migration file as `{ up, down }` + its file-derived logical name. */\nexport const loadMigration = async (\n dir: string,\n file: string,\n): Promise<MigrationModule & { name: string }> => {\n const mod = (await import(pathToFileURL(join(dir, file)).href)) as MigrationModule;\n // The FILE decides the identity — a module-exported `name` must not override\n // it (two files with colliding module exports would merge into one journal row).\n return { ...mod, name: migrationNameOf(file) };\n};\n\n/** Ensure the migration directory exists. */\nexport const ensureMigrationDir = async (dir: string): Promise<void> => {\n await mkdir(dir, { recursive: true });\n};\n\n/** The next free numeric prefix (max existing + 1). */\nexport const nextMigrationNumber = async (dir: string): Promise<number> => {\n const files = await readdir(dir);\n return (\n files.reduce((max, file) => {\n const match = MIGRATION_FILE.exec(file);\n return match ? Math.max(max, Number(match[1])) : max;\n }, 0) + 1\n );\n};\n","/**\n * The `_migrations` journal — lease-based bookkeeping so concurrent runners\n * can't apply the same migration twice:\n *\n * - `claim` atomically inserts a fresh `running` row carrying a LEASE\n * (`expiresAt`). An existing row is only stolen when its lease has\n * expired (hard-crash recovery) and NEVER when `status: 'applied'`.\n * A unique index on `name` arbitrates concurrent inserts.\n * - `renew` extends the lease while a long `up()` is still running, so a\n * slow backfill can't be stolen out from under a live runner.\n * - `markApplied` flips `status` AFTER `up()` succeeds; if the running row\n * vanished concurrently it re-inserts an `applied` row so the migration\n * is never silently re-applied on the next run.\n *\n * All operations are best-effort where losing a race is harmless.\n */\nimport type { Document } from 'mongodb';\nimport { JOURNAL_COLLECTION, type JournalManager } from './types.ts';\n\nexport interface MigrationJournal {\n /** Names considered applied (status `applied` or legacy rows with no status). */\n appliedNames(): Promise<Set<string>>;\n /**\n * Atomically claim a migration under a lease of `leaseMs`. Returns true only\n * for the winning runner: fresh insert, or steal of an EXPIRED non-applied\n * row. Live claims held by other runners are never stolen.\n */\n claim(name: string, file: string, leaseMs: number): Promise<boolean>;\n /** Extend the lease of a still-running claim (heartbeat during long `up()`s). */\n renew(name: string, leaseMs: number): Promise<void>;\n /** Flip a claimed migration to `applied` (after `up()` succeeded). */\n markApplied(name: string): Promise<void>;\n /** Remove a `running` row (on failure, so the migration can be re-run). */\n removeRunning(name: string): Promise<void>;\n /** Delete a migration's journal row (rollback). */\n unrecord(name: string): Promise<void>;\n}\n\nconst isDuplicateKeyError = (err: unknown): boolean => {\n const code = (err as { code?: number } | null)?.code;\n if (code === 11000 || code === 11001) return true;\n return /E11000 duplicate key/.test(String((err as Error | null)?.message ?? ''));\n};\n\n/** Build the journal operations over a `JournalManager` (a connected manager). */\nexport const createMigrationJournal = (manager: JournalManager): MigrationJournal => {\n // Idempotent uniqueness guard: two runners racing `claim` must not both be\n // able to INSERT a fresh row. Created lazily once per journal instance;\n // failure is tolerated (single-runner setups still work).\n let indexReady = false;\n const ensureIndex = async (): Promise<void> => {\n if (indexReady) return;\n try {\n await manager.createIndex?.(JOURNAL_COLLECTION, { name: 1 }, { unique: true });\n } catch {\n // Best-effort: managers without createIndex (or a failed creation)\n // still work single-runner.\n }\n indexReady = true;\n };\n\n const appliedNames = async (): Promise<Set<string>> => {\n const rows = await manager.findMany(JOURNAL_COLLECTION);\n return new Set(\n rows\n // `status` is absent on legacy (pre-status) rows — treat those as applied.\n .filter((row) => row.status === undefined || row.status === 'applied')\n .map((row) => row.name as string),\n );\n };\n\n /**\n * Rows another runner may take over: an unapplied row whose lease expired,\n * or any legacy/corrupt row without `status: 'running'|'applied'`.\n * (`$ne`/`$nin` match missing fields in Mongo, so status-less legacy rows\n * land in the last branch.)\n */\n const stealableFilter = (name: string, now: Date, staleCutoff: Date): Document => ({\n name,\n status: { $ne: 'applied' },\n $or: [\n { expiresAt: { $lt: now } },\n { expiresAt: { $exists: false }, appliedAt: { $lt: staleCutoff } },\n { status: { $nin: ['running', 'applied'] } },\n ],\n });\n\n const claim = async (name: string, file: string, leaseMs: number): Promise<boolean> => {\n await ensureIndex();\n const now = new Date();\n const expiresAt = new Date(Date.now() + leaseMs);\n\n // Step 1 — steal an existing STEALABLE row (expired lease / legacy crash).\n const stole = await manager.findOneAndUpdate(\n JOURNAL_COLLECTION,\n stealableFilter(name, now, new Date(Date.now() - leaseMs)),\n { $set: { status: 'running', appliedAt: now, file, expiresAt } },\n { returnDocument: 'before' },\n );\n if (stole !== null) return true;\n\n // Step 2 — either the row exists but is NOT stealable (applied, or a live\n // claim), or it doesn't exist yet. Try a fresh insert; the unique index\n // decides who wins a concurrent race.\n try {\n await manager.insertOne(JOURNAL_COLLECTION, {\n name,\n appliedAt: now,\n status: 'running',\n file,\n expiresAt,\n });\n return true;\n } catch (err) {\n if (isDuplicateKeyError(err)) return false;\n throw err;\n }\n };\n\n const renew = async (name: string, leaseMs: number): Promise<void> => {\n await manager.updateOne(\n JOURNAL_COLLECTION,\n { name, status: 'running' },\n { $set: { expiresAt: new Date(Date.now() + leaseMs) } },\n );\n };\n\n const markApplied = async (name: string): Promise<void> => {\n const res = (await manager.updateOne(\n JOURNAL_COLLECTION,\n { name, status: 'running' },\n { $set: { status: 'applied' } },\n )) as { matchedCount?: number } | unknown | null;\n // updateOne RESOLVES (never rejects) on zero matches — if the running row\n // was removed concurrently we MUST restore an applied row, otherwise the\n // next `up()` re-runs an already-applied migration.\n if ((res as { matchedCount?: number })?.matchedCount === 0) {\n await manager\n .insertOne(JOURNAL_COLLECTION, { name, appliedAt: new Date(), status: 'applied' })\n .catch(() => {});\n }\n };\n\n const removeRunning = async (name: string): Promise<void> => {\n await manager.deleteOne(JOURNAL_COLLECTION, { name, status: 'running' }).catch(() => {});\n };\n\n const unrecord = async (name: string): Promise<void> => {\n await manager.deleteOne(JOURNAL_COLLECTION, { name });\n };\n\n return { appliedNames, claim, renew, markApplied, removeRunning, unrecord };\n};\n","/**\n * File-based migration runner — `createMongoMigrationRunner`. Orchestrates the\n * two sub-systems:\n *\n * - `./files.ts` — discover / load / scaffold `NNN_name.ts` files\n * - `./journal.ts` — lease-based `_migrations` journal (atomic, crash-safe)\n *\n * `up()` applies pending migrations in numeric order under an exclusive claim\n * with an auto-renewed lease (long migrations can't be stolen by another\n * runner, but a crashed runner's claim expires); `down()` rolls back applied\n * migrations in reverse order and validates its target BEFORE destroying\n * anything; `status()` reports applied/pending; `create()` scaffolds a new file\n * atomically (`wx` — concurrent scaffolds never clobber each other).\n */\n\nimport { writeFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\nimport type { LoggerLike } from '../utils/logger.ts';\nimport {\n ensureMigrationDir,\n listMigrationFiles,\n loadMigration,\n migrationNameOf,\n nextMigrationNumber,\n} from './files.ts';\nimport { createMigrationJournal } from './journal.ts';\nimport type { JournalManager, MongoMigrationRunner, MongoMigrationRunnerOptions } from './types.ts';\n\n/** The `service` shape the runner needs (one connected manager + config/logger). */\ninterface MigrationService {\n db: Record<string, unknown>;\n logger: LoggerLike;\n config?: { migrationDir?: string };\n}\n\nconst DEFAULT_LEASE_MS = 120_000;\n\nexport const createMongoMigrationRunner = (\n service: MigrationService,\n options: MongoMigrationRunnerOptions = {},\n): MongoMigrationRunner => {\n const migrationDir = options.migrationDir ?? service.config?.migrationDir ?? './migrations';\n const logger = options.logger ?? service.logger;\n const leaseMs = options.leaseMs ?? DEFAULT_LEASE_MS;\n\n const manager = (): JournalManager => {\n const keys = Object.keys(service.db);\n // Explicit option first; otherwise the first connected key. In multi-DB\n // services insertion order is arbitrary — pass `db:` explicitly.\n const key = options.db !== undefined ? options.db : keys[0];\n const db = key ? (service.db[key] as JournalManager | undefined) : undefined;\n if (!db) {\n throw new Error(\n options.db !== undefined && !keys.includes(options.db)\n ? `Unknown database \"${options.db}\" — connected: ${keys.join(', ')}`\n : 'No database client connected — call service.makeConnections() first',\n );\n }\n return db;\n };\n\n /** Heartbeat that keeps a running claim's lease alive during a long `up()`. */\n const startHeartbeat = (journal: ReturnType<typeof createMigrationJournal>, name: string) => {\n const timer = setInterval(\n () => {\n void journal.renew(name, leaseMs).catch(() => {});\n },\n Math.max(leaseMs / 2, 1_000),\n );\n // Never hold the event loop open just for the heartbeat.\n timer.unref?.();\n return () => clearInterval(timer);\n };\n\n const up = async (): Promise<void> => {\n await ensureMigrationDir(migrationDir);\n const journal = createMigrationJournal(manager());\n\n const files = await listMigrationFiles(migrationDir);\n const applied = await journal.appliedNames();\n const pending = files.filter((file) => !applied.has(migrationNameOf(file)));\n\n for (const file of pending) {\n const migration = await loadMigration(migrationDir, file);\n logger.info({ name: migration.name }, 'running migration up');\n // Exclusive lease-based claim: fresh rows insert, expired claims steal,\n // applied/live rows reject. `status` flips to `applied` only AFTER\n // `up()` succeeds.\n if (!(await journal.claim(migration.name, basename(file), leaseMs))) {\n logger.info(\n { name: migration.name },\n 'migration claimed by another runner or already applied, skipping',\n );\n continue;\n }\n const stopHeartbeat = startHeartbeat(journal, migration.name);\n try {\n await migration.up({ service, logger, name: migration.name });\n await journal.markApplied(migration.name);\n } catch (err) {\n await journal.removeRunning(migration.name);\n throw err;\n } finally {\n stopHeartbeat();\n }\n logger.info({ name: migration.name }, 'migration applied');\n }\n };\n\n const down = async (targetName?: string): Promise<void> => {\n const files = await listMigrationFiles(migrationDir);\n // Validate the target BEFORE touching the DB: a typo'd name must fail\n // loudly instead of silently rolling back EVERYTHING.\n if (targetName !== undefined) {\n const known = files.some((file) => migrationNameOf(file) === targetName);\n if (!known) {\n throw new Error(\n `down(): unknown migration \"${targetName}\" — known: ${files.map(migrationNameOf).join(', ') || '(none)'}`,\n );\n }\n }\n const journal = createMigrationJournal(manager());\n const applied = await journal.appliedNames();\n const appliedFiles = files.filter((file) => applied.has(migrationNameOf(file))).reverse();\n\n for (const file of appliedFiles) {\n const migration = await loadMigration(migrationDir, file);\n logger.info({ name: migration.name }, 'running migration down');\n await migration.down({ service, logger, name: migration.name });\n await journal.unrecord(migration.name);\n logger.info({ name: migration.name }, 'migration rolled back');\n if (targetName !== undefined && migration.name === targetName) break;\n }\n };\n\n const status = async (): Promise<{ applied: string[]; pending: string[] }> => {\n const files = await listMigrationFiles(migrationDir);\n const applied = await createMigrationJournal(manager()).appliedNames();\n const all = files.map(migrationNameOf);\n return {\n applied: all.filter((name) => applied.has(name)),\n pending: all.filter((name) => !applied.has(name)),\n };\n };\n\n const create = async (name: string): Promise<string> => {\n await ensureMigrationDir(migrationDir);\n const template = `import type { MigrationContext } from '@ignex/ninox';\n\nexport const up = async (ctx: MigrationContext): Promise<void> => {\n // const users = ctx.service.db.primaryClient;\n // await users.createSchema('users');\n};\n\nexport const down = async (ctx: MigrationContext): Promise<void> => {\n // const users = ctx.service.db.primaryClient;\n // await users.client.dropCollection('users');\n};\n`;\n // Atomic scaffold: `wx` fails if the file appeared between our number\n // scan and the write (concurrent `create()` calls), so we bump + retry\n // instead of silently overwriting someone else's migration.\n for (;;) {\n const next = await nextMigrationNumber(migrationDir);\n const padded = String(next).padStart(3, '0');\n const fileName = `${padded}_${name}.ts`;\n const filePath = join(migrationDir, fileName);\n try {\n await writeFile(filePath, template, { encoding: 'utf8', flag: 'wx' });\n logger.info({ name, file: fileName }, 'migration scaffolded');\n return filePath;\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === 'EEXIST') continue;\n throw err;\n }\n }\n };\n\n return { up, down, status, create };\n};\n\n// Re-export the public migration types so the folder barrel matches the old\n// single-module exports.\nexport type {\n MigrationContext,\n MigrationModule,\n MongoMigrationRunner,\n MongoMigrationRunnerOptions,\n} from './types.ts';\n","import type { ClientSession, MongoClient } from 'mongodb';\nimport { isMongoTransientError } from './errors/index.ts';\nimport type { LoggerLike } from './utils/logger.ts';\nimport { sleep } from './utils/timeout.ts';\n\nexport { isMongoTransientError, TRANSIENT_MONGO_ERROR_CODES } from './errors/index.ts';\n\nexport interface RetryOptions {\n maxAttempts?: number;\n delayMs?: number;\n logger?: LoggerLike;\n}\n\n/**\n * Retry `fn` while it throws a *transient* Mongo error (network / not-primary /\n * sharding / server-selection during failover), with exponential backoff\n * `delayMs * 2^attempt` plus ±20% jitter — synchronized retry waves against a\n * recovering cluster amplify outages instead of absorbing them. Domain errors\n * and genuine data errors are never retried.\n */\nexport const withRetry = async <T>(\n fn: () => Promise<T>,\n options: RetryOptions = {},\n): Promise<T> => {\n const maxAttempts = Math.max(1, options.maxAttempts ?? 3);\n const delayMs = options.delayMs ?? 150;\n const logger = options.logger;\n\n let attempt = 0;\n let lastError: unknown;\n while (attempt < maxAttempts) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n attempt += 1;\n if (attempt >= maxAttempts || !isMongoTransientError(err)) throw err;\n const base = delayMs * 2 ** (attempt - 1);\n // ±20% jitter around the exponential backoff.\n const backoff = Math.round(base * (0.8 + Math.random() * 0.4));\n logger?.debug?.({ attempt, backoffMs: backoff, error: (err as Error)?.message }, 'retrying');\n await sleep(backoff);\n }\n }\n // The loop above runs at least once and either returns or throws, so this is\n // unreachable in practice — but it guarantees `maxAttempts: 0` never turns\n // into `throw undefined`.\n throw lastError ?? new Error('withRetry: no attempt was made (maxAttempts must be >= 1)');\n};\n\n/**\n * Manual transaction helper: start → run → commit, aborting + ending the\n * session on any failure. Prefer the service-level `transaction()` which also\n * handles capability detection and unsupported-server fallback.\n */\nexport const withTransaction = async <T>(\n client: MongoClient,\n fn: (session: ClientSession) => Promise<T>,\n): Promise<T> => {\n const session = client.startSession();\n try {\n session.startTransaction();\n const result = await fn(session);\n await session.commitTransaction();\n return result;\n } catch (err) {\n await session.abortTransaction().catch(() => {});\n throw err;\n } finally {\n // Never let a failing `endSession` mask the original error.\n await session.endSession().catch(() => {});\n }\n};\n","/** Default cap for list/pagination limits (mirrors sdk-db). */\nexport const DEFAULT_MAX_LIMIT = 1000;\n\n/** Default limit applied to `findMany` when none is provided. */\nexport const DEFAULT_FIND_LIMIT = 100;\n\n/**\n * Hard cap for a single `insertMany` / `bulkWrite` / `bulkUpsert` call (the\n * driver splits at 100k; anything above is almost certainly an unbounded caller\n * array). Above this the ORM throws `BadRequest` instead of spiking memory.\n */\nexport const MAX_BATCH_OPS = 100_000;\n","import type {\n Collection,\n Document,\n Filter,\n FindCursor,\n FindOptions,\n Hint,\n Sort,\n WithId,\n} from 'mongodb';\nimport { BadRequest } from '../errors/index.ts';\nimport type { QueryOptions } from '../service/query-options.ts';\nimport { DEFAULT_FIND_LIMIT } from '../shared/constants.ts';\nimport type { FilterInput } from '../shared/filter-types.ts';\n\n/**\n * Execution context provided by the CRUD layer. `run` participates in the\n * uniform trace + retry + cache + in-flight-dedup pipeline and returns the\n * merged driver options to the execute closure.\n */\nexport interface QueryBuilderContext<TDoc extends Document> {\n physicalName: string;\n collection: Collection<TDoc>;\n run: <T>(\n opName: string,\n filter: FilterInput<TDoc>,\n execute: (driverOpts: FindOptions) => Promise<T>,\n options?: QueryOptions,\n ) => Promise<T>;\n}\n\n/**\n * Merge an incoming filter into the current one WITHOUT silently dropping\n * clauses: plain-object values are treated as operator documents\n * (`{ $gte: 18 }`) and deep-merged per key so\n * `.where({ age: { $gte: 18 } }).where({ age: { $lte: 65 } })`\n * yields `{ age: { $gte: 18, $lte: 65 } }` instead of losing the `$gte`.\n * Scalars/arrays replace (last write wins), matching Mongo semantics.\n */\nconst mergeFilterKey = (prev: unknown, next: unknown): unknown => {\n if (\n prev !== null &&\n typeof prev === 'object' &&\n !Array.isArray(prev) &&\n next !== null &&\n typeof next === 'object' &&\n !Array.isArray(next)\n ) {\n return { ...(prev as Document), ...(next as Document) };\n }\n return next;\n};\n\n/**\n * Lazy, fluent, IMMUTABLE, schema-typed query builder. Every chain method\n * returns a NEW builder — a stored base query can be safely reused as a\n * template without derived chains contaminating it:\n *\n * const admins = users.query('users').where({ role: 'admin' });\n * await admins.where({ age: { $gte: 18 } }).many(); // base unchanged\n *\n * Nothing hits the database until an executor (`one`/`many`/`cursor`/`count`/\n * `exists`) is called. Projections via `select` are pushed to the driver so\n * only requested fields are transferred.\n */\nexport class QueryBuilder<TDoc extends Document, TSelection = TDoc> {\n private _filter: FilterInput<TDoc> = {};\n private _sort?: Sort;\n private _skip?: number;\n private _limit?: number;\n private _projection?: Document;\n private _options: QueryOptions = {};\n\n constructor(private readonly ctx: QueryBuilderContext<TDoc>) {}\n\n get filter(): FilterInput<TDoc> {\n return this._filter;\n }\n\n /** Copy-on-write fork used by every chain method. */\n private fork(): QueryBuilder<TDoc, TSelection> {\n const next = new QueryBuilder<TDoc, TSelection>(this.ctx);\n next._filter = this._filter;\n if (this._sort !== undefined) next._sort = this._sort;\n if (this._skip !== undefined) next._skip = this._skip;\n if (this._limit !== undefined) next._limit = this._limit;\n if (this._projection !== undefined) next._projection = this._projection;\n next._options = { ...this._options };\n return next;\n }\n\n /** Merge a filter into the current one (operator docs deep-merge per key). */\n where(filter: FilterInput<TDoc>): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n const merged: Document = { ...(next._filter as Document) };\n for (const [key, value] of Object.entries(filter as Document)) {\n merged[key] = key in merged ? mergeFilterKey(merged[key], value) : value;\n }\n next._filter = merged as FilterInput<TDoc>;\n return next;\n }\n\n /** AND-combine the current filter with a new one (stays flat across repeats). */\n and(filter: FilterInput<TDoc>): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n const current = next._filter as Document;\n const existing = Array.isArray(current.$and)\n ? (current.$and as Document[])\n : Object.keys(current).length > 0\n ? [current]\n : [];\n next._filter = { $and: [...existing, filter] } as unknown as FilterInput<TDoc>;\n return next;\n }\n\n /**\n * OR-combine: current filter AND (filter1 OR filter2 ...). Requires at least\n * one filter — an empty `$or` is rejected by the server.\n */\n or(...filters: Array<FilterInput<TDoc>>): QueryBuilder<TDoc, TSelection> {\n if (filters.length === 0) {\n throw new BadRequest('QueryBuilder.or() requires at least one filter');\n }\n return this.and((filters.length === 1 ? filters[0]! : { $or: filters }) as FilterInput<TDoc>);\n }\n\n /** Set the sort order (`{ field: 1 | -1 }`). */\n sort(sort: Sort): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._sort = sort;\n return next;\n }\n\n /** Skip the first `n` matching documents. */\n skip(n: number): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._skip = n;\n return next;\n }\n\n /** Limit the result set to `n` documents. */\n limit(n: number): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._limit = n;\n return next;\n }\n\n /** Project only the given fields — the projection is pushed to the driver. */\n select<const K extends keyof TSelection>(\n fields: readonly K[],\n ): QueryBuilder<TDoc, Pick<TSelection, K>> {\n const next = this.fork() as unknown as QueryBuilder<TDoc, Pick<TSelection, K>>;\n const projection: Record<string, 1> = {};\n for (const field of fields) projection[field as string] = 1;\n (next as unknown as { _projection?: Document })._projection = projection;\n return next;\n }\n\n /** Raw projection document (`{ field: 1 }` / `{ field: 0 }`). */\n project(projection: Document): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._projection = projection;\n return next;\n }\n\n /** Set the index hint. */\n hint(hint: Hint): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.hint = hint;\n return next;\n }\n\n /** Set the driver cursor batch size. */\n batchSize(n: number): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.batchSize = n;\n return next;\n }\n\n /** Run the query inside a transaction session. */\n session(session: NonNullable<QueryOptions['session']>): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.session = session;\n return next;\n }\n\n /** Cap server-side execution time. */\n maxTimeMS(ms: number): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.maxTimeMS = ms;\n return next;\n }\n\n /** Bypass the read cache for this query when `false`. */\n cache(on: boolean): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.cache = on;\n return next;\n }\n\n /** Override in-flight dedup for this query when set. */\n dedupe(on: boolean): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.dedupe = on;\n return next;\n }\n\n /** Compile the builder into driver options (does not execute). */\n private compile(): FindOptions & QueryOptions {\n const out: FindOptions & QueryOptions = { ...this._options };\n if (this._sort) out.sort = this._sort;\n if (this._skip !== undefined) out.skip = this._skip;\n if (this._limit !== undefined) out.limit = this._limit;\n if (this._projection) out.projection = this._projection;\n return out;\n }\n\n private countOptions(): FindOptions & QueryOptions {\n // countDocuments accepts skip/limit/session/hint/maxTimeMS but NOT sort/projection.\n const out: FindOptions & QueryOptions = { ...this._options };\n if (this._skip !== undefined) out.skip = this._skip;\n if (this._limit !== undefined) out.limit = this._limit;\n return out;\n }\n\n /** Fetch one document (limit forced to 1). */\n async one(): Promise<WithId<TSelection> | null> {\n const options = this.compile();\n if (options.limit === undefined) options.limit = 1;\n return this.ctx.run<WithId<TSelection> | null>(\n 'mongo.getOne',\n this._filter,\n (opts) =>\n this.ctx.collection.findOne(\n this._filter as unknown as Filter<TDoc>,\n opts,\n ) as unknown as Promise<WithId<TSelection> | null>,\n options,\n );\n }\n\n /** Fetch many documents (default limit 100 when unset). */\n async many(): Promise<WithId<TSelection>[]> {\n const options = this.compile();\n if (options.limit === undefined) options.limit = DEFAULT_FIND_LIMIT;\n return this.ctx.run<WithId<TSelection>[]>(\n 'mongo.findMany',\n this._filter,\n (opts) =>\n this.ctx.collection\n .find(this._filter as unknown as Filter<TDoc>, opts)\n .toArray() as unknown as Promise<WithId<TSelection>[]>,\n options,\n );\n }\n\n /** Streaming cursor (raw driver cursor; no retry/cache/drift — caller-owned). */\n cursor(): FindCursor<WithId<TDoc>> {\n return this.ctx.collection.find(\n this._filter as unknown as Filter<TDoc>,\n this.compile() as FindOptions,\n );\n }\n\n /** Count matching documents. */\n async count(): Promise<number> {\n return this.ctx.run(\n 'mongo.countDocuments',\n this._filter,\n (opts) => this.ctx.collection.countDocuments(this._filter as unknown as Filter<TDoc>, opts),\n this.countOptions() as QueryOptions,\n );\n }\n\n /** True when at least one document matches (`_id`-only projection — no doc transfer). */\n async exists(): Promise<boolean> {\n const options = this.compile();\n if (options.limit === undefined) options.limit = 1;\n options.projection = { _id: 1 };\n const doc = await this.ctx.run<WithId<TDoc> | null>(\n 'mongo.exists',\n this._filter,\n (opts) =>\n this.ctx.collection.findOne(\n this._filter as unknown as Filter<TDoc>,\n opts,\n ) as unknown as Promise<WithId<TDoc> | null>,\n options,\n );\n return doc !== null;\n }\n}\n","/**\n * Relation definitions used by `populate`. Relations declare how documents in\n * one collection reference documents in another; `populate` then resolves them\n * with DataLoader-batched `$in` queries (1 + N queries total, not 1 + N×M).\n */\nimport type { Document } from 'mongodb';\nimport type { RemoveIndexSignature } from '../shared/types.ts';\nimport type {\n DbClientsDefinition,\n ExtractCollectionNames,\n ExtractCollectionType,\n ExtractDbNames,\n} from '../types.ts';\n\nexport interface RelationDefBase {\n /** Foreign logical collection. */\n collection: string;\n /** Field on the source document holding the reference key(s). */\n localField: string;\n /** Field on the foreign document to match (default `_id`). */\n foreignField?: string;\n /** Field name attached to the source document after population. */\n as: string;\n /** Optional: max keys per batched `$in` query. */\n maxBatchSize?: number;\n /** Optional: cache resolved relations on the loader (default true). */\n cache?: boolean;\n /** When true, a missing belongsTo target attaches `undefined` instead of `null`. */\n optional?: boolean;\n}\n\nexport interface BelongsToRelation extends RelationDefBase {\n type: 'belongsTo';\n}\n\nexport interface HasManyRelation extends RelationDefBase {\n type: 'hasMany';\n}\n\nexport interface ManyToManyRelation extends RelationDefBase {\n type: 'manyToMany';\n through: {\n /** Join collection (logical). */\n collection: string;\n /** Field on the join doc pointing at the source doc. */\n localField: string;\n /** Field on the join doc pointing at the target doc. */\n foreignField: string;\n };\n}\n\nexport type RelationDef = BelongsToRelation | HasManyRelation | ManyToManyRelation;\n\n/* ------------------------------------------------------------------ *\n * Schema-validated relation types. `populate` constrains each relation\n * against the schema registry: `collection` must be a known collection,\n * `localField` a field on the source doc, `foreignField` a field on the\n * target doc, and `through.*` fields on the join doc.\n * ------------------------------------------------------------------ */\n\ntype RelColNames<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> = ExtractCollectionNames<TClients, TDb>;\n\ntype RelDocOf<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n C extends RelColNames<TClients, TDb>,\n> = ExtractCollectionType<TClients, TDb, C>;\n\n/** Field-name union of a doc, excluding Mongo `Document`'s index-signature keys. */\ntype RelField<T> = Extract<keyof RemoveIndexSignature<T>, string>;\n\n/** Validates one relation object `R` against the source doc and the registry. */\nexport type ValidRelation<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n TSource extends Document,\n R,\n> = R extends { type: 'belongsTo'; collection: infer C }\n ? C extends RelColNames<TClients, TDb>\n ? Omit<R, 'localField' | 'foreignField'> & {\n localField: RelField<TSource>;\n foreignField?: RelField<RelDocOf<TClients, TDb, C>>;\n }\n : never\n : R extends { type: 'hasMany'; collection: infer C }\n ? C extends RelColNames<TClients, TDb>\n ? Omit<R, 'localField' | 'foreignField'> & {\n localField: RelField<TSource>;\n foreignField?: RelField<RelDocOf<TClients, TDb, C>>;\n }\n : never\n : R extends {\n type: 'manyToMany';\n collection: infer C;\n through: { collection: infer TC };\n }\n ? C extends RelColNames<TClients, TDb>\n ? TC extends RelColNames<TClients, TDb>\n ? Omit<R, 'localField' | 'foreignField' | 'through'> & {\n localField: RelField<TSource>;\n foreignField?: RelField<RelDocOf<TClients, TDb, C>>;\n through: {\n collection: TC;\n localField: RelField<RelDocOf<TClients, TDb, TC>>;\n foreignField: RelField<RelDocOf<TClients, TDb, TC>>;\n };\n }\n : never\n : never\n : never;\n\n/**\n * Maps a tuple of relations to the joined `as` fields attached to result docs.\n * `belongsTo` resolves to `Doc | null`; `hasMany` / `manyToMany` to `Doc[]`.\n */\nexport type JoinedFields<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n R extends readonly unknown[],\n> = {\n [K in keyof R as K extends `${number}`\n ? R[K] extends { as: infer A extends string }\n ? A\n : never\n : never]: R[K] extends { type: 'belongsTo'; collection: infer C }\n ? C extends RelColNames<TClients, TDb>\n ? RelDocOf<TClients, TDb, C> | null\n : never\n : R[K] extends { type: 'hasMany' | 'manyToMany'; collection: infer C }\n ? C extends RelColNames<TClients, TDb>\n ? RelDocOf<TClients, TDb, C>[]\n : never\n : never;\n};\n\ntype BelongsToConfig<C extends string, A extends string, L extends string, F extends string> = Omit<\n BelongsToRelation,\n 'type' | 'collection' | 'as' | 'localField' | 'foreignField'\n> & {\n collection: C;\n as: A;\n localField: L;\n foreignField?: F;\n};\n\ntype HasManyConfig<C extends string, A extends string, L extends string, F extends string> = Omit<\n HasManyRelation,\n 'type' | 'collection' | 'as' | 'localField' | 'foreignField'\n> & {\n collection: C;\n as: A;\n localField: L;\n foreignField?: F;\n};\n\ntype ManyToManyConfig<\n C extends string,\n A extends string,\n L extends string,\n TC extends string,\n F extends string,\n TLoc extends string,\n TFor extends string,\n> = Omit<\n ManyToManyRelation,\n 'type' | 'collection' | 'as' | 'localField' | 'foreignField' | 'through'\n> & {\n collection: C;\n as: A;\n localField: L;\n foreignField?: F;\n through: {\n collection: TC;\n localField: TLoc;\n foreignField: TFor;\n };\n};\n\n/** One source doc → at most one foreign doc (defaults `foreignField: '_id'`). */\nexport const belongsTo = <\n const C extends string,\n const A extends string,\n const L extends string,\n const F extends string = '_id',\n>(\n config: BelongsToConfig<C, A, L, F>,\n): BelongsToRelation & { collection: C; as: A; localField: L; foreignField: F } =>\n ({\n type: 'belongsTo',\n foreignField: '_id',\n ...config,\n }) as BelongsToRelation & { collection: C; as: A; localField: L; foreignField: F };\n\n/** One source doc → many foreign docs (defaults `foreignField: '_id'`). */\nexport const hasMany = <\n const C extends string,\n const A extends string,\n const L extends string,\n const F extends string = '_id',\n>(\n config: HasManyConfig<C, A, L, F>,\n): HasManyRelation & { collection: C; as: A; localField: L; foreignField: F } =>\n ({\n type: 'hasMany',\n foreignField: '_id',\n ...config,\n }) as HasManyRelation & { collection: C; as: A; localField: L; foreignField: F };\n\n/** Source doc → join docs → target docs through a pivot collection. */\nexport const manyToMany = <\n const C extends string,\n const A extends string,\n const L extends string,\n const TC extends string,\n const F extends string = '_id',\n const TLoc extends string = '_id',\n const TFor extends string = '_id',\n>(\n config: ManyToManyConfig<C, A, L, TC, F, TLoc, TFor>,\n): ManyToManyRelation & {\n collection: C;\n as: A;\n localField: L;\n foreignField: F;\n through: { collection: TC; localField: TLoc; foreignField: TFor };\n} =>\n ({\n type: 'manyToMany',\n foreignField: '_id',\n ...config,\n }) as ManyToManyRelation & {\n collection: C;\n as: A;\n localField: L;\n foreignField: F;\n through: { collection: TC; localField: TLoc; foreignField: TFor };\n };\n","/**\n * Optional repository layer over a `CollectionManager` — a thin, domain-typed\n * convenience wrapper. The op-based core API is unchanged; a repository just\n * binds a manager + collection name so call sites don't repeat the collection\n * literal, and adds small ergonomic helpers (`getById`, `getByIds`,\n * `updateVersioned`, `exists`, …).\n *\n * There is deliberately NO change tracking / unit-of-work: `getById` → mutate →\n * `update`/`updateVersioned` is explicit, matching the core op semantics. All\n * perf features (cache, dedup, batching, populate) and collection hooks /\n * timestamps apply transparently because every method delegates to the manager.\n */\nimport type {\n AggregationCursor,\n ChangeStream,\n ChangeStreamOptions,\n DeleteResult,\n Document,\n FindOneAndUpdateOptions,\n InsertManyResult,\n InsertOneOptions,\n InsertOneResult,\n UpdateOptions,\n UpdateResult,\n} from 'mongodb';\nimport type { PopulateOptions } from '../relation/populate.ts';\nimport type { JoinedFields, RelationDef, ValidRelation } from '../relation/relation.ts';\nimport type { AggregationStages } from '../service/aggregation-stages.ts';\nimport type {\n FindQueryOptions,\n InsertInput,\n VersionedUpdateResult,\n} from '../service/crud/index.ts';\nimport type { CollectionManager } from '../service/index.ts';\nimport type {\n CursorPage,\n CursorPaginationConfig,\n PaginationConfig,\n} from '../service/pagination/index.ts';\nimport type { PipelineBuilder } from '../service/pipeline-builder.ts';\nimport type { QueryOptions } from '../service/query-options.ts';\nimport type { UpdateInput } from '../service/update-types.ts';\nimport type { FilterInput } from '../shared/filter-types.ts';\nimport type { PaginationResult } from '../shared/pagination-result.ts';\nimport type {\n DbClientsDefinition,\n ExtractCollectionNames,\n ExtractCollectionType,\n ExtractDbNames,\n} from '../types.ts';\n\nexport interface RepositoryOptions {\n /** Default `findMany` limit (defaults to the ORM's `DEFAULT_FIND_LIMIT`). */\n limit?: number;\n}\n\n/** Repository for one collection — type is derived from the manager + name. */\nexport type Repository<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n C extends ExtractCollectionNames<TClients, TDb>,\n> = RepositoryFor<TClients, TDb, C, ExtractCollectionType<TClients, TDb, C>>;\n\ntype RepositoryFor<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n C extends ExtractCollectionNames<TClients, TDb>,\n Doc extends Document,\n> = {\n readonly collection: C;\n /** The underlying manager — escape hatch to any op. */\n readonly manager: CollectionManager<TClients, TDb>;\n\n /* reads */\n /** Fetch one doc by primary key, or `null`. */\n getById(id: Doc['_id'], options?: FindQueryOptions<Doc>): Promise<Doc | null>;\n /** Fetch many docs by primary key (`$in`). */\n getByIds(ids: readonly Doc['_id'][], options?: FindQueryOptions<Doc>): Promise<Doc[]>;\n /** Fetch one doc by filter, or `null`. */\n findOne(filter?: FilterInput<Doc>, options?: FindQueryOptions<Doc>): Promise<Doc | null>;\n /** Fetch one doc by filter or throw `NOT_FOUND`. */\n findOneOrFail(filter?: FilterInput<Doc>, options?: FindQueryOptions<Doc>): Promise<Doc>;\n /** Fetch many docs (default limit from `RepositoryOptions.limit`). */\n findMany(filter?: FilterInput<Doc>, options?: FindQueryOptions<Doc>): Promise<Doc[]>;\n /** Fetch many non-soft-deleted docs. */\n findActive(filter?: FilterInput<Doc>, options?: FindQueryOptions<Doc>): Promise<Doc[]>;\n /** Count docs matching a filter. */\n count(filter?: FilterInput<Doc>, options?: QueryOptions): Promise<number>;\n /** Whether at least one doc matches. */\n exists(filter?: FilterInput<Doc>, options?: FindQueryOptions<Doc>): Promise<boolean>;\n /** Distinct values of `field`. */\n distinct<K extends keyof Doc>(\n field: K,\n filter?: FilterInput<Doc>,\n options?: FindQueryOptions<Doc>,\n ): Promise<Array<Doc[K]>>;\n\n /* writes */\n /** Insert one doc. */\n create(\n doc: InsertInput<Doc>,\n options?: InsertOneOptions & QueryOptions,\n ): Promise<InsertOneResult<Doc>>;\n /** Insert many docs. */\n createMany(\n docs: readonly InsertInput<Doc>[],\n options?: QueryOptions,\n ): Promise<InsertManyResult<Doc>>;\n /** Update one doc by primary key. */\n update(\n id: Doc['_id'],\n patch: UpdateInput<Doc>,\n options?: UpdateOptions & QueryOptions,\n ): Promise<UpdateResult<Doc>>;\n /** Optimistic-lock update by primary key (`__v` CAS). */\n updateVersioned(\n id: Doc['_id'],\n patch: UpdateInput<Doc>,\n options?: FindOneAndUpdateOptions & QueryOptions,\n ): Promise<VersionedUpdateResult<Doc>>;\n /** Delete one doc by primary key. */\n deleteById(id: Doc['_id'], options?: QueryOptions): Promise<DeleteResult>;\n /** Soft-delete one doc by primary key (sets `deletedAt`). */\n softDelete(id: Doc['_id'], options?: QueryOptions): Promise<UpdateResult<Doc>>;\n\n /* pagination */\n /** `$facet` pagination with totals (one round trip). */\n page(filter: FilterInput<Doc>, config?: PaginationConfig): Promise<PaginationResult<Doc>>;\n /** Keyset/cursor pagination (O(log n), no totals). */\n pageCursor(filter: FilterInput<Doc>, config: CursorPaginationConfig): Promise<CursorPage<Doc>>;\n\n /* aggregation */\n /** Type-safe chained aggregation builder. */\n pipeline(options?: QueryOptions): PipelineBuilder<TClients, TDb, Doc>;\n /** Callback aggregation over a typed stage builder. */\n aggregate(\n stages: (s: AggregationStages<Doc, TClients, TDb>) => Document[],\n options?: QueryOptions,\n ): Promise<AggregationCursor<Document>>;\n\n /* relations */\n /** DataLoader-batched relation population (no N+1). */\n populate<const T extends Document, const R extends readonly RelationDef[]>(\n docs: T[],\n relations: R & { [K in keyof R]: ValidRelation<TClients, TDb, T, R[K]> },\n options?: PopulateOptions,\n ): Promise<Array<T & JoinedFields<TClients, TDb, R>>>;\n\n /* realtime */\n /** Change stream (caller-owned — attach `error` listener + close). */\n watch(pipeline?: Document[], options?: ChangeStreamOptions): ChangeStream<Doc>;\n};\n\n/**\n * Bind a repository to a manager + collection. `Doc` is inferred from the\n * collection name — no `<TDoc>` at call sites.\n */\nexport const createRepository = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n C extends ExtractCollectionNames<TClients, TDb>,\n>(\n manager: CollectionManager<TClients, TDb>,\n collection: C,\n options: RepositoryOptions = {},\n): Repository<TClients, TDb, C> => {\n const repo: Repository<TClients, TDb, C> = {\n collection,\n manager,\n\n getById: (id, o) => manager.getOne(collection, { _id: id }, o),\n getByIds: (ids, o) => manager.findMany(collection, { _id: { $in: ids } }, o),\n findOne: (filter, o) => manager.getOne(collection, filter, o),\n findOneOrFail: (filter, o) => manager.getOneOrFail(collection, filter, o),\n findMany: (filter, o) =>\n manager.findMany(collection, filter, {\n // Repository `limit` is a DEFAULT — a per-call option must win.\n ...(options.limit !== undefined ? { limit: options.limit } : {}),\n ...(o ?? {}),\n }),\n findActive: (filter, o) => manager.findActive(collection, filter, o),\n count: (filter, o) => manager.countDocuments(collection, filter, o),\n exists: async (filter, o) =>\n (await manager.getOne(collection, filter, { ...(o ?? {}), projection: { _id: 1 } })) !== null,\n distinct: (field, filter, o) => manager.distinct(collection, field, filter, o),\n\n create: (doc, o) => manager.insertOne(collection, doc, o),\n createMany: (docs, o) => manager.insertMany(collection, docs, o),\n update: (id, patch, o) => manager.updateOne(collection, { _id: id }, patch, o),\n updateVersioned: (id, patch, o) => manager.updateWithVersion(collection, { _id: id }, patch, o),\n deleteById: (id, o) => manager.deleteOne(collection, { _id: id }, o),\n softDelete: (id, o) => manager.softDeleteOne(collection, { _id: id }, o),\n\n page: (filter, config) => manager.paginateFlexible(collection, filter, config),\n pageCursor: (filter, config) => manager.paginateCursor(collection, filter, config),\n\n pipeline: (o) => manager.pipeline(collection, o),\n aggregate: (stages, o) => manager.aggregate(collection, stages, o),\n\n // The repository's public signature already validates `relations` at the\n // call site; the manager's mapped-type param can't be re-inferred here\n // (TS mapped-type inference friction), so delegate through the validated\n // shape without weakening the public type.\n populate: (docs, relations, o) => manager.populate(docs, relations as never, o),\n\n watch: (pipeline, options) => manager.watchCollection(collection, pipeline, options),\n };\n return repo;\n};\n","/**\n * Schema-driven collection registry.\n *\n * Collection names are carried by the schema itself (`s.object({...}, { name })`\n * or `defineCollection(name, schema, extras)`), so the ORM's `collections` map\n * is *derived* from the schemas instead of hand-typed. The keys of the derived\n * map ARE the schema names — a typo'd collection name becomes a type error\n * everywhere (CRUD, query builder, relations, populate).\n *\n * const users = s.object(\n * { _id: s.objectId(), email: s.string() },\n * { name: 'users' },\n * );\n * const orders = defineCollection('orders', s.object({ ... }), {\n * indexes: [{ key: { userId: 1 } }],\n * });\n *\n * const dbClients = {\n * primary: {\n * name: 'app',\n * collections: defineCollections(users, orders),\n * },\n * };\n */\n\nimport type { HookMap } from '../hooks/hooks.ts';\nimport type {\n CollectionDefinition,\n CollectionLike,\n CollectionTimestamps,\n IndexSpec,\n} from '../types.ts';\nimport type { InferDoc } from './infer.ts';\nimport type { ObjectField, SchemaType } from './types.ts';\n\n/** An object schema that carries its collection name. */\nexport type NamedObjectField<N extends string = string> = ObjectField<\n Record<string, SchemaType>,\n N\n> & {\n name: N;\n};\n\n/** A collection definition (schema + optional indexes/hooks) that carries its name. */\nexport type NamedCollectionDefinition<\n N extends string = string,\n S extends ObjectField = ObjectField,\n> = CollectionDefinition<S & { name: N }> & { name: N };\n\n/** Either form accepted by `defineCollections`. */\nexport type NamedCollection =\n | (ObjectField & { name: string })\n | ({\n schema: ObjectField;\n indexes?: IndexSpec[];\n hooks?: HookMap<any>;\n timestamps?: CollectionTimestamps | boolean;\n } & { name: string });\n\n/** Extract the carried collection name from a named collection item. */\ntype StringName<T> = T extends { name: infer N } ? Extract<N, string> : never;\n\nexport type CollectionName<T> = T extends { schema: infer S } ? StringName<S> : StringName<T>;\n\n/** The value placed in the derived `collections` map for a given item. */\nexport type CollectionValue<T> = T extends {\n schema: infer S;\n indexes?: infer _Ix;\n hooks?: infer _Hk;\n}\n ? CollectionDefinition<Extract<S, ObjectField>>\n : T;\n\n/** The derived `collections` map type: keyed by each item's carried name. */\nexport type CollectionMap<T extends readonly NamedCollection[]> = {\n [K in T[number] as CollectionName<K>]: CollectionValue<K>;\n};\n\nconst resolveItemName = (item: NamedCollection): string =>\n 'schema' in item\n ? ((item as NamedCollectionDefinition).schema as NamedObjectField).name\n : (item as NamedObjectField).name;\n\n/**\n * Fail fast when `timestamps: true | {...}` names fields the schema does not\n * declare. Under strict validation (`additionalProperties: false`, the\n * default) an undeclared timestamp field gets EVERY insert/update rejected\n * server-side with an opaque `DocumentValidationFailure` — far from this\n * misconfiguration site. Throwing here turns that into a one-line fix.\n */\nconst assertTimestampsDeclared = (\n name: string,\n schema: ObjectField,\n timestamps: CollectionTimestamps | boolean,\n): void => {\n const ts = typeof timestamps === 'boolean' ? {} : timestamps;\n const createdAt = ts.createdAt ?? 'createdAt';\n const updatedAt = ts.updatedAt ?? 'updatedAt';\n const properties = schema.properties ?? {};\n for (const field of [createdAt, updatedAt]) {\n if (!(field in properties)) {\n throw new Error(\n `defineCollections: \"${name}\" enables timestamps but its schema does not declare the ` +\n `field \"${field}\". Add \\`${field}: s.date().optional()\\` to the schema (or adjust ` +\n `\\`timestamps\\`) — otherwise strict validation rejects every stamped write.`,\n );\n }\n }\n};\n\nconst resolveItemValue = (item: NamedCollection): CollectionLike => {\n if ('schema' in item) {\n const def = item as NamedCollectionDefinition;\n if (def.timestamps !== undefined) {\n assertTimestampsDeclared(def.name, def.schema, def.timestamps);\n }\n return {\n schema: def.schema,\n ...(def.indexes ? { indexes: def.indexes } : {}),\n ...(def.hooks ? { hooks: def.hooks } : {}),\n ...(def.timestamps !== undefined ? { timestamps: def.timestamps } : {}),\n };\n }\n return item as NamedObjectField;\n};\n\n/**\n * Attach a collection name to a schema (plus optional indexes/hooks) and return\n * a `CollectionDefinition`-shaped item. When no extras are needed this is\n * equivalent to `s.object({...}, { name })`.\n */\nexport const defineCollection = <N extends string, S extends ObjectField>(\n name: N,\n schema: S,\n extras: {\n indexes?: IndexSpec[];\n hooks?: HookMap<InferDoc<S>>;\n timestamps?: CollectionTimestamps | boolean;\n } = {},\n): NamedCollectionDefinition<N, S> => {\n const namedSchema = { ...(schema as object), name } as S & { name: N };\n if (extras.timestamps !== undefined) {\n assertTimestampsDeclared(name, schema, extras.timestamps);\n }\n return {\n name,\n schema: namedSchema,\n ...(extras.indexes ? { indexes: extras.indexes } : {}),\n ...(extras.hooks ? { hooks: extras.hooks } : {}),\n ...(extras.timestamps !== undefined ? { timestamps: extras.timestamps } : {}),\n } as NamedCollectionDefinition<N, S>;\n};\n\n/**\n * Derive a `collections` map from schemas that carry their own names. Throws on\n * duplicate names. The returned map's keys are the schema names and its values\n * are valid `CollectionLike` entries, so it plugs directly into\n * `DBClientDefinition.collections` with full type inference.\n */\nexport const defineCollections = <const T extends readonly NamedCollection[]>(\n ...items: T\n): CollectionMap<T> => {\n const out: Record<string, unknown> = {};\n for (const item of items) {\n const name = resolveItemName(item);\n if (name in out) {\n throw new Error(`defineCollections: duplicate collection name \"${name}\"`);\n }\n out[name] = resolveItemValue(item);\n }\n return out as CollectionMap<T>;\n};\n","import type { MongoJsonSchema } from './json-schema.ts';\nimport type { ObjectField, SchemaType } from './types.ts';\n\nexport type { MongoJsonSchema } from './json-schema.ts';\n\n/**\n * Schema → MongoDB `$jsonSchema` validator conversion. This is the ORM's\n * headline feature: one schema definition drives TS types AND server-side\n * document validation + collection creation.\n *\n * Mapping (mirrors sdk-db `convertJsonSchemaToMongoSchema`):\n * string→string, integer→int, number→number, double→double, long→long,\n * decimal→decimal, boolean→bool, date→date, objectId→objectId,\n * array→array(items), object→object(properties/required),\n * enum→enum (+bsonType), null→null, any→no constraint, raw→fragment verbatim.\n * The top-level `_id` is forced to `objectId` regardless of declared type.\n */\n\n/** Copy numeric keywords (min/max/exclusive/multipleOf) onto a fragment. */\nconst addNumericBounds = (\n out: MongoJsonSchema,\n field: {\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n },\n): MongoJsonSchema => {\n if (field.minimum !== undefined) out.minimum = field.minimum;\n if (field.maximum !== undefined) out.maximum = field.maximum;\n if (field.multipleOf !== undefined) out.multipleOf = field.multipleOf;\n if (field.exclusiveMinimum) out.exclusiveMinimum = true;\n if (field.exclusiveMaximum) out.exclusiveMaximum = true;\n return out;\n};\n\n/**\n * The Node driver picks the BSON wire type for a plain JS `number` by VALUE:\n * integral values in int32 range serialize as `int`, everything else as\n * `double` (and explicit `Long` instances as `long`). A single-type\n * `bsonType` therefore rejects perfectly type-correct TS values — e.g.\n * `bsonType: 'int'` rejects 3_000_000_000 (encoded as double), and\n * `bsonType: 'double'` rejects `{ rating: 5 }` (encoded as int). Numeric\n * kinds must accept every wire encoding their TS type can produce:\n * - `double` → ['double','int','long'] (any IEEE value the driver emits)\n * - `integer` → ['int','long','double'] + multipleOf: 1\n * - `long` → ['long','int','double'] + multipleOf: 1\n * For the integral kinds `multipleOf: 1` preserves SERVER-side integrality\n * enforcement that a bare double member of the union would otherwise lose.\n */\nconst NUMERIC_WIRE_UNION: Record<'double' | 'long', string[]> = {\n double: ['double', 'int', 'long'],\n long: ['long', 'int', 'double'],\n};\nconst INTEGER_WIRE_UNION = ['int', 'long', 'double'];\n\nconst convertField = (field: SchemaType): MongoJsonSchema => {\n // Raw escape hatch: pass the fragment through verbatim. A `description` on\n // the DSL field is merged only when the fragment doesn't already carry one.\n if (field.kind === 'raw') {\n const out = { ...field.fragment };\n if (field.description && !out.description) out.description = field.description;\n return out;\n }\n\n const out: MongoJsonSchema = {};\n if (field.description) out.description = field.description;\n\n switch (field.kind) {\n case 'string':\n out.bsonType = 'string';\n if (field.minLength !== undefined) out.minLength = field.minLength;\n if (field.maxLength !== undefined) out.maxLength = field.maxLength;\n if (field.pattern) out.pattern = field.pattern;\n // `format` is intentionally NOT emitted: MongoDB's `$jsonSchema` rejects the\n // keyword with `$jsonSchema keyword 'format' is not currently supported`, so\n // emitting it would make `createCollection`/`collMod` fail server-side. The\n // DSL option remains accepted for authoring intent, but it is a no-op here.\n return out;\n case 'number':\n out.bsonType = field.integer ? [...INTEGER_WIRE_UNION] : 'number';\n // Server-side integrality: the double member of the union would accept\n // fractional values — `multipleOf: 1` rejects them again.\n if (field.integer && field.multipleOf === undefined) out.multipleOf = 1;\n return addNumericBounds(out, field);\n case 'double':\n out.bsonType = [...NUMERIC_WIRE_UNION.double];\n return addNumericBounds(out, field);\n case 'long':\n out.bsonType = [...NUMERIC_WIRE_UNION.long];\n if (field.multipleOf === undefined) out.multipleOf = 1;\n return addNumericBounds(out, field);\n case 'decimal':\n out.bsonType = 'decimal';\n return addNumericBounds(out, field);\n case 'boolean':\n out.bsonType = 'bool';\n return out;\n case 'date':\n out.bsonType = 'date';\n return out;\n case 'objectId':\n out.bsonType = 'objectId';\n return out;\n case 'geoPoint':\n return {\n ...(field.description ? { description: field.description } : {}),\n bsonType: 'object',\n required: ['type', 'coordinates'],\n properties: {\n type: { enum: ['Point'] },\n coordinates: {\n bsonType: 'array',\n items: { bsonType: 'number' },\n minItems: 2,\n maxItems: 2,\n },\n },\n };\n case 'null':\n out.bsonType = 'null';\n return out;\n case 'any':\n return out;\n case 'enum': {\n out.enum = [...field.values];\n // `bsonType` and `enum` are AND-ed by Mongo's `$jsonSchema`. The old\n // behavior picked ONE bsonType from the first non-null member, which\n // silently excluded members of other types server-side (a mixed enum\n // like `s.enum(['a', 1])` only ever accepted strings). Emit the union\n // of every member's type so the enum set is the sole constraint:\n // ['a', 1] → bsonType ['string', 'int']\n // ['x', null] → bsonType ['string', 'null']\n // [1, 2, 3] → bsonType 'int' (unchanged)\n // [1, 2.5] → bsonType 'number' (matches every numeric BSON type)\n // [null] → bsonType 'null'\n const types = new Set<string>();\n for (const v of field.values) {\n if (v === null) types.add('null');\n else if (typeof v === 'string') types.add('string');\n else if (typeof v === 'number') {\n const allInt = field.values.every((x) => typeof x !== 'number' || Number.isInteger(x));\n // Out-of-int32-range members serialize as double — 'int' alone would\n // reject them, so fall back to the full numeric union.\n const fitsInt32 =\n allInt &&\n field.values.every(\n (x) => typeof x !== 'number' || (x >= -2147483648 && x <= 2147483647),\n );\n types.add(allInt && fitsInt32 ? 'int' : 'number');\n break; // 'int'/'number' already covers every numeric member\n }\n }\n if (types.size === 1) {\n out.bsonType = [...types][0]!;\n } else if (types.size > 1) {\n out.bsonType = [...types];\n }\n return out;\n }\n case 'array':\n out.bsonType = 'array';\n out.items = convertField(field.items);\n if (field.minItems !== undefined) out.minItems = field.minItems;\n if (field.maxItems !== undefined) out.maxItems = field.maxItems;\n if (field.uniqueItems) out.uniqueItems = true;\n return out;\n case 'object':\n return convertObject(field);\n }\n};\n\nconst convertObject = (field: ObjectField): MongoJsonSchema => {\n const out: MongoJsonSchema = { bsonType: 'object' };\n const required: string[] = [];\n const properties: Record<string, MongoJsonSchema> = {};\n\n for (const [key, prop] of Object.entries(field.properties)) {\n properties[key] = convertField(prop);\n if (!prop.flags.optional && !prop.flags.hasDefault) required.push(key);\n }\n\n if (required.length > 0) out.required = required;\n out.properties = properties;\n // Strict by default: the DB `$jsonSchema` validator is the ONLY runtime\n // validation layer (per project decision — no client-side schema validation),\n // so unknown fields are rejected unless a field explicitly opts out\n // (`additionalProperties: true`).\n out.additionalProperties = field.additionalProperties ?? false;\n if (field.minProperties !== undefined) out.minProperties = field.minProperties;\n if (field.maxProperties !== undefined) out.maxProperties = field.maxProperties;\n return out;\n};\n\n/**\n * ORM-managed lifecycle fields the library itself writes, reserved in the\n * validator so strict validation (`additionalProperties: false`) doesn't\n * reject them — the same treatment `_id` already gets:\n * `__v` — optimistic-lock version counter (`updateWithVersion`)\n * `deletedAt` — soft-delete marker (`softDeleteOne`); `null` means active\n * Only injected when the schema does NOT already declare the field. Exported\n * so the runtime drift validator (`validate-doc.ts`) stays in sync.\n */\nexport const ORM_RESERVED_FIELDS: Record<string, MongoJsonSchema> = {\n __v: { bsonType: 'int' },\n deletedAt: { bsonType: ['date', 'null'] },\n};\n\n/** Convert an object schema into a Mongo JSON-schema fragment (no `$jsonSchema` wrapper). */\nexport const toMongoSchema = (schema: ObjectField): MongoJsonSchema => {\n const result = convertObject(schema);\n result.properties ??= {};\n // Only inject `_id` when the schema does NOT declare it. MongoDB's default is\n // ObjectId, and because validation is strict by default the implicit `_id`\n // must be a declared property or every insert is rejected by the DB validator.\n // A user-declared `_id` is respected as-is (e.g. `s.string()` for string ids),\n // so the inferred TS type (InferDoc) and the DB validator stay in agreement.\n if (!result.properties._id) {\n result.properties._id = { bsonType: 'objectId' };\n }\n // Reserve the ORM's own lifecycle fields so soft-delete and optimistic\n // locking keep working under strict validation.\n for (const [key, fragment] of Object.entries(ORM_RESERVED_FIELDS)) {\n if (!result.properties[key]) result.properties[key] = fragment;\n }\n return result;\n};\n\n/** Full validator object ready for `createCollection({ validator })` / `collMod`. */\nexport const toMongoValidator = (schema: ObjectField): { $jsonSchema: MongoJsonSchema } => ({\n $jsonSchema: toMongoSchema(schema),\n});\n","/**\n * Typed schema DSL for `ninox`.\n *\n * Schemas are plain, serializable objects (kind + constraints + flags). They\n * serve three purposes at once:\n * 1. Derive the TypeScript document type (`InferDoc<T>`)\n * 2. Drive the fluent query builder's field typing\n * 3. Convert to a MongoDB `$jsonSchema` validator (`toMongoValidator`)\n *\n * Example:\n * const userSchema = s.object({\n * _id: s.objectId(),\n * email: s.string().optional(),\n * age: s.integer({ minimum: 0 }),\n * role: s.enum(['admin', 'user'] as const),\n * createdAt: s.date(),\n * });\n * type User = InferDoc<typeof userSchema>;\n */\nimport type { MongoJsonSchema } from './json-schema.ts';\n\nexport interface FieldFlags {\n optional: boolean;\n hasDefault: boolean;\n defaultValue?: unknown;\n}\n\nexport interface FieldMeta {\n kind: string;\n flags: FieldFlags;\n description?: string;\n}\n\nexport interface StringField extends FieldMeta {\n kind: 'string';\n format?: string;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n}\n\nexport interface IntegerField extends FieldMeta {\n kind: 'number';\n integer: true;\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n /** Draft-4 boolean form: `minimum` is excluded from the allowed range. */\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\nexport interface NumberField extends FieldMeta {\n kind: 'number';\n integer?: false;\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\n/** Strict BSON `double` (IEEE 754 float64) field. */\nexport interface DoubleField extends FieldMeta {\n kind: 'double';\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\n/** Strict BSON `long` (int64) field — inferred as `number` (precision caveat). */\nexport interface LongField extends FieldMeta {\n kind: 'long';\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\n/** Strict BSON `decimal` (Decimal128) field — inferred as `Decimal128`. */\nexport interface DecimalField extends FieldMeta {\n kind: 'decimal';\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\nexport interface BooleanField extends FieldMeta {\n kind: 'boolean';\n}\n\nexport interface DateField extends FieldMeta {\n kind: 'date';\n}\n\nexport interface ObjectIdField extends FieldMeta {\n kind: 'objectId';\n}\n\nexport interface ArrayField<I extends SchemaType = SchemaType> extends FieldMeta {\n kind: 'array';\n items: I;\n minItems?: number;\n maxItems?: number;\n uniqueItems?: boolean;\n}\n\nexport interface ObjectField<\n P extends Record<string, SchemaType> = Record<string, SchemaType>,\n N extends string = string,\n> extends FieldMeta {\n kind: 'object';\n properties: P;\n additionalProperties?: boolean;\n minProperties?: number;\n maxProperties?: number;\n /**\n * Optional collection name carried by the schema. When present, the schema is\n * the single source of truth for the collection name — `defineCollections`\n * keys the derived `collections` map by it.\n */\n name?: N;\n}\n\nexport interface EnumField<V extends readonly (string | number)[] = readonly (string | number)[]>\n extends FieldMeta {\n kind: 'enum';\n values: V;\n}\n\nexport interface AnyField extends FieldMeta {\n kind: 'any';\n}\n\nexport interface NullField extends FieldMeta {\n kind: 'null';\n}\n\nexport interface GeoPointField extends FieldMeta {\n kind: 'geoPoint';\n}\n\nexport interface RawField extends FieldMeta {\n kind: 'raw';\n /** Arbitrary `$jsonSchema` fragment passed through verbatim (escape hatch). */\n fragment: MongoJsonSchema;\n}\n\nexport type SchemaType =\n | StringField\n | IntegerField\n | NumberField\n | DoubleField\n | LongField\n | DecimalField\n | BooleanField\n | DateField\n | ObjectIdField\n | ArrayField\n | ObjectField\n | EnumField\n | AnyField\n | NullField\n | GeoPointField\n | RawField;\n\n/** A schema with chainable `.optional()` / `.default()` modifiers attached. */\nexport type Chainable<T extends SchemaType> = T & {\n optional(): Chainable<T & { flags: { optional: true } }>;\n default(value: unknown): Chainable<T & { flags: { hasDefault: true; defaultValue: unknown } }>;\n};\n\nconst chain = <T extends SchemaType>(field: T): Chainable<T> => {\n const obj = field as unknown as Chainable<T>;\n obj.optional = () => chain({ ...field, flags: { ...field.flags, optional: true } });\n obj.default = (value: unknown) =>\n chain({ ...field, flags: { ...field.flags, hasDefault: true, defaultValue: value } });\n return obj;\n};\n\nconst BASE = { flags: { optional: false, hasDefault: false } } as const;\n\n/**\n * Object schema factory (exposed as `s.object`). When `name` is provided the\n * returned schema carries it as a required literal, so `defineCollections` can\n * key the derived map by it and forget a name becomes a type error.\n */\nfunction objectField<P extends Record<string, SchemaType>, N extends string>(\n properties: P,\n opts: {\n additionalProperties?: boolean;\n minProperties?: number;\n maxProperties?: number;\n name: N;\n },\n): Chainable<ObjectField<P, N> & { name: N }>;\nfunction objectField<P extends Record<string, SchemaType>>(\n properties: P,\n opts?: { additionalProperties?: boolean; minProperties?: number; maxProperties?: number },\n): Chainable<ObjectField<P, string>>;\nfunction objectField<P extends Record<string, SchemaType>, N extends string = string>(\n properties: P,\n opts: {\n additionalProperties?: boolean;\n minProperties?: number;\n maxProperties?: number;\n name?: N;\n } = {},\n): Chainable<ObjectField<P, N> & { name?: N }> {\n return chain({ kind: 'object', properties, ...BASE, ...opts });\n}\n\n/** Numeric constraints shared by every numeric field kind. */\nexport type NumberBounds = {\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n};\n\nexport const s = {\n /** UTF-8 string field (optional `format` / length / regex constraints). */\n string(\n opts: { format?: string; minLength?: number; maxLength?: number; pattern?: string } = {},\n ): Chainable<StringField> {\n return chain({ kind: 'string', ...BASE, ...opts });\n },\n /** 32-bit integer field with optional bounds (min/max, exclusive, multipleOf). */\n integer(opts: NumberBounds = {}): Chainable<IntegerField> {\n return chain({ kind: 'number', integer: true, ...BASE, ...opts });\n },\n /** Double/float field with optional bounds (min/max, exclusive, multipleOf). */\n number(opts: NumberBounds = {}): Chainable<NumberField> {\n return chain({ kind: 'number', integer: false, ...BASE, ...opts });\n },\n /** Strict BSON `double` (IEEE 754 float64) field. */\n double(opts: NumberBounds = {}): Chainable<DoubleField> {\n return chain({ kind: 'double', ...BASE, ...opts });\n },\n /** Strict BSON `long` (int64) field — inferred as `number`. */\n long(opts: NumberBounds = {}): Chainable<LongField> {\n return chain({ kind: 'long', ...BASE, ...opts });\n },\n /** Strict BSON `decimal` (Decimal128) field — inferred as `Decimal128`. */\n decimal(opts: NumberBounds = {}): Chainable<DecimalField> {\n return chain({ kind: 'decimal', ...BASE, ...opts });\n },\n /** Boolean field. */\n boolean(): Chainable<BooleanField> {\n return chain({ kind: 'boolean', ...BASE });\n },\n /** UTC datetime field (BSON date). */\n date(): Chainable<DateField> {\n return chain({ kind: 'date', ...BASE });\n },\n /** MongoDB ObjectId field (`_id` and foreign keys). */\n objectId(): Chainable<ObjectIdField> {\n return chain({ kind: 'objectId', ...BASE });\n },\n /** Array of `items` (nested schema types allowed), with optional length/uniqueness. */\n array<I extends SchemaType>(\n items: I,\n opts: { minItems?: number; maxItems?: number; uniqueItems?: boolean } = {},\n ): Chainable<ArrayField<I>> {\n const field: ArrayField<I> = { kind: 'array', items, ...BASE, ...opts };\n return chain(field);\n },\n object: objectField,\n /** Enum union of literal string/number values. */\n enum<V extends readonly (string | number)[]>(values: V): Chainable<EnumField<V>> {\n const field: EnumField<V> = { kind: 'enum', values, ...BASE };\n return chain(field);\n },\n /** Unconstrained field (no validator bounds). */\n any(): Chainable<AnyField> {\n return chain({ kind: 'any', ...BASE });\n },\n /** Explicitly-nullable field. */\n null(): Chainable<NullField> {\n return chain({ kind: 'null', ...BASE });\n },\n /** GeoJSON Point field (type `Point` + `[lng, lat]` coordinates) for `2dsphere` queries. */\n geoPoint(): Chainable<GeoPointField> {\n return chain({ kind: 'geoPoint', ...BASE });\n },\n /**\n * Raw `$jsonSchema` escape hatch: pass an arbitrary fragment through verbatim\n * to the validator. Use for Mongo keywords the DSL doesn't model (e.g.\n * `patternProperties`, `allOf`, `anyOf`, `dependencies`).\n */\n jsonSchema(fragment: MongoJsonSchema): Chainable<RawField> {\n return chain({ kind: 'raw', fragment, ...BASE });\n },\n};\n\n/** Standalone modifier: mark a field as optional (`s.string().optional()` equivalent). */\nexport const optional = <T extends SchemaType>(\n field: T,\n): Chainable<T & { flags: { optional: true } }> =>\n chain({ ...field, flags: { ...field.flags, optional: true } });\n\n/** Standalone modifier: attach a default value. */\nexport const withDefault = <T extends SchemaType>(\n field: T,\n value: unknown,\n): Chainable<T & { flags: { hasDefault: true; defaultValue: unknown } }> =>\n chain({ ...field, flags: { ...field.flags, hasDefault: true, defaultValue: value } });\n","/**\n * Shared building blocks for the drift validator: issue recording, value\n * description / BSON-type checks, and numeric-bounds + reserved-field checks.\n * All pure — no schema/doc knowledge, just value-level helpers.\n */\nimport { Decimal128, Long, ObjectId } from 'mongodb';\nimport { ORM_RESERVED_FIELDS } from '../to-mongo-schema.ts';\nimport type { DriftIssue, DriftIssueCode } from './types.ts';\n\n/** Append a drift issue. */\nexport const push = (\n issues: DriftIssue[],\n path: string,\n code: DriftIssueCode,\n expected: string,\n message: string,\n): void => {\n issues.push({ path, code, expected, message });\n};\n\n/** Human-readable description of a runtime value (used in type-mismatch messages). */\nexport const describeValue = (value: unknown): string => {\n if (value instanceof ObjectId) return 'ObjectId';\n if (value instanceof Date) return 'Date';\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n return typeof value;\n};\n\n/** Is `value` a plain BSON/JSON object — excludes arrays, dates, ObjectIds, RegExps. */\nexport const isPlainObject = (value: unknown): boolean =>\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !(value instanceof ObjectId) &&\n !(value instanceof RegExp);\n\n/** Coerce a value to a finite number for numeric-constraint checks (BSON-aware). */\nexport const numericValue = (value: unknown): number | undefined => {\n if (value instanceof Decimal128) {\n const n = Number(value.toString());\n return Number.isNaN(n) ? undefined : n;\n }\n // `Long` above 2^53 loses precision via toNumber, but bounds checks are\n // advisory — skipping them silently (the old behavior) is worse.\n if (value instanceof Long) {\n const n = value.toNumber();\n return Number.isNaN(n) ? undefined : n;\n }\n if (typeof value === 'number' && !Number.isNaN(value)) return value;\n return undefined;\n};\n\n/** Shared numeric-bounds shape present on every numeric field kind. */\nexport interface NumericBounds {\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\n/** Emit drift issues for numeric bounds shared by every numeric field kind. */\nexport const checkNumericBounds = (\n field: NumericBounds,\n value: unknown,\n path: string,\n issues: DriftIssue[],\n): void => {\n const num = numericValue(value);\n if (num === undefined) return;\n if (\n field.minimum !== undefined &&\n (field.exclusiveMinimum ? num <= field.minimum : num < field.minimum)\n ) {\n push(\n issues,\n path,\n 'constraint',\n `minimum ${field.minimum}${field.exclusiveMinimum ? ' (exclusive)' : ''}`,\n `${num} out of range`,\n );\n }\n if (\n field.maximum !== undefined &&\n (field.exclusiveMaximum ? num >= field.maximum : num > field.maximum)\n ) {\n push(\n issues,\n path,\n 'constraint',\n `maximum ${field.maximum}${field.exclusiveMaximum ? ' (exclusive)' : ''}`,\n `${num} out of range`,\n );\n }\n if (field.multipleOf !== undefined && field.multipleOf > 0 && num % field.multipleOf !== 0) {\n push(\n issues,\n path,\n 'constraint',\n `multipleOf ${field.multipleOf}`,\n `${num} is not a multiple of ${field.multipleOf}`,\n );\n }\n};\n\n/** Does `value` satisfy a single `$jsonSchema` bsonType keyword? */\nexport const bsonTypeMatches = (bsonType: string | undefined, value: unknown): boolean => {\n switch (bsonType) {\n case 'objectId':\n return value instanceof ObjectId;\n case 'int':\n return typeof value === 'number' && Number.isInteger(value);\n case 'number':\n return typeof value === 'number' && !Number.isNaN(value);\n case 'string':\n return typeof value === 'string';\n case 'bool':\n return typeof value === 'boolean';\n case 'date':\n return value instanceof Date;\n case 'null':\n return value === null;\n case 'array':\n return Array.isArray(value);\n case 'object':\n return isPlainObject(value);\n case 'double':\n return typeof value === 'number' && !Number.isNaN(value);\n case 'long':\n return (typeof value === 'number' && Number.isInteger(value)) || value instanceof Long;\n case 'decimal':\n return value instanceof Decimal128;\n default:\n return true;\n }\n};\n\n/** Validate a value against a `MongoJsonSchema` fragment (used for reserved fields). */\nexport const checkReservedValue = (\n key: string,\n value: unknown,\n path: string,\n issues: DriftIssue[],\n): void => {\n const fragment = (ORM_RESERVED_FIELDS as Record<string, { bsonType?: string | string[] }>)[key];\n if (!fragment) return;\n const types = Array.isArray(fragment.bsonType) ? fragment.bsonType : [fragment.bsonType];\n if (types.some((t) => bsonTypeMatches(t, value))) return;\n push(\n issues,\n path,\n 'type',\n types.join(' | '),\n `Reserved field \"${key}\" must be ${types.join(' | ')}`,\n );\n};\n","/**\n * Per-kind drift validators as a lookup table of pure functions — the\n * functional-composition replacement for what was a single giant `switch` over\n * `field.kind` in `validate-doc.ts`.\n *\n * Each validator receives `deps` (the shared recursive entry points\n * `validateValue` / `validateObjectProps`) so array/object kinds can recurse\n * without importing the orchestrator — breaking the import cycle and keeping\n * every field-kind rule small, isolated, and independently readable.\n */\nimport { Decimal128, type Document, Long, ObjectId } from 'mongodb';\nimport type {\n ArrayField,\n DecimalField,\n DoubleField,\n EnumField,\n LongField,\n NumberField,\n ObjectField,\n SchemaType,\n StringField,\n} from '../types.ts';\nimport { checkNumericBounds, describeValue, isPlainObject, push } from './helpers.ts';\nimport type { DriftIssue } from './types.ts';\n\n/** The recursive entry points the per-kind validators use to descend. */\nexport interface FieldValidatorDeps {\n validateValue: (field: SchemaType, value: unknown, path: string, issues: DriftIssue[]) => void;\n validateObjectProps: (\n field: ObjectField,\n value: Document,\n path: string,\n issues: DriftIssue[],\n topLevel: boolean,\n ) => void;\n}\n\nexport type FieldValidator = (\n deps: FieldValidatorDeps,\n field: SchemaType,\n value: unknown,\n path: string,\n issues: DriftIssue[],\n) => void;\n\n/**\n * Compiled-pattern cache: `s.string({ pattern })` is compiled once per schema\n * field object instead of once per validated VALUE (the old\n * `new RegExp(f.pattern)` ran on every string of every document — measurable\n * GC pressure under `findMany` drift checks). Keyed weakly so schemas are not\n * kept alive by the cache.\n */\nconst patternCache = new WeakMap<object, RegExp>();\n\nconst compiledPattern = (field: StringField): RegExp | undefined => {\n if (!field.pattern) return undefined;\n const cached = patternCache.get(field);\n if (cached) return cached;\n try {\n const re = new RegExp(field.pattern);\n patternCache.set(field, re);\n return re;\n } catch {\n // Malformed pattern — nothing to enforce at runtime.\n return undefined;\n }\n};\n\nconst stringValidator: FieldValidator = (_deps, field, value, path, issues) => {\n const f = field as StringField;\n if (typeof value !== 'string') {\n push(issues, path, 'type', 'string', `Expected string, got ${describeValue(value)}`);\n return;\n }\n if (f.minLength !== undefined && value.length < f.minLength) {\n push(\n issues,\n path,\n 'constraint',\n `string(minLength ${f.minLength})`,\n `Length ${value.length} < ${f.minLength}`,\n );\n }\n if (f.maxLength !== undefined && value.length > f.maxLength) {\n push(\n issues,\n path,\n 'constraint',\n `string(maxLength ${f.maxLength})`,\n `Length ${value.length} > ${f.maxLength}`,\n );\n }\n const pattern = compiledPattern(f);\n if (pattern && !pattern.test(value)) {\n push(\n issues,\n path,\n 'constraint',\n `string(pattern ${f.pattern})`,\n `\"${value}\" does not match pattern`,\n );\n }\n};\n\nconst numberValidator: FieldValidator = (_deps, field, value, path, issues) => {\n const f = field as NumberField;\n const expected = f.integer ? 'integer' : 'number';\n if (typeof value !== 'number' || Number.isNaN(value)) {\n push(issues, path, 'type', expected, `Expected ${expected}, got ${describeValue(value)}`);\n return;\n }\n if (f.integer && !Number.isInteger(value)) {\n push(issues, path, 'type', 'integer', `Expected integer, got ${value}`);\n }\n checkNumericBounds(f, value, path, issues);\n};\n\nconst floatingValidator: FieldValidator = (_deps, field, value, path, issues) => {\n const f = field as DoubleField | LongField | DecimalField;\n // `long` accepts both safe-range JS numbers and driver `Long` instances —\n // int64 values above 2^53 deserialized by another client come back as Long,\n // and flagging legitimately-stored large values as drift is a false positive.\n const ok =\n f.kind === 'decimal'\n ? value instanceof Decimal128\n : f.kind === 'long'\n ? (typeof value === 'number' && Number.isInteger(value)) || value instanceof Long\n : typeof value === 'number' && !Number.isNaN(value);\n if (!ok) {\n push(issues, path, 'type', f.kind, `Expected ${f.kind}, got ${describeValue(value)}`);\n return;\n }\n checkNumericBounds(f, value, path, issues);\n};\n\nconst booleanValidator: FieldValidator = (_deps, _field, value, path, issues) => {\n if (typeof value !== 'boolean') {\n push(issues, path, 'type', 'boolean', `Expected boolean, got ${describeValue(value)}`);\n }\n};\n\nconst dateValidator: FieldValidator = (_deps, _field, value, path, issues) => {\n if (!(value instanceof Date)) {\n push(issues, path, 'type', 'date', `Expected Date, got ${describeValue(value)}`);\n }\n};\n\nconst objectIdValidator: FieldValidator = (_deps, _field, value, path, issues) => {\n if (!(value instanceof ObjectId)) {\n push(issues, path, 'type', 'ObjectId', `Expected ObjectId, got ${describeValue(value)}`);\n }\n};\n\nconst geoPointValidator: FieldValidator = (_deps, _field, value, path, issues) => {\n if (!isPlainObject(value)) {\n push(issues, path, 'type', 'GeoPoint', `Expected GeoPoint object, got ${describeValue(value)}`);\n return;\n }\n const gp = value as Document;\n if (gp.type !== 'Point') {\n push(\n issues,\n path,\n 'enum',\n 'GeoPoint(type \"Point\")',\n `Expected type \"Point\", got ${JSON.stringify(gp.type)}`,\n );\n }\n const coords = gp.coordinates;\n if (\n !Array.isArray(coords) ||\n coords.length !== 2 ||\n !coords.every((c) => typeof c === 'number' && Number.isFinite(c))\n ) {\n push(\n issues,\n path,\n 'constraint',\n 'GeoPoint(coordinates: [lng, lat])',\n 'Expected [lng, lat] pair of finite numbers',\n );\n }\n};\n\nconst nullValidator: FieldValidator = (_deps, _field, value, path, issues) => {\n if (value !== null) {\n push(issues, path, 'type', 'null', `Expected null, got ${describeValue(value)}`);\n }\n};\n\nconst anyValidator: FieldValidator = () => {\n // `any` accepts any value — nothing to check.\n};\n\nconst rawValidator: FieldValidator = () => {\n // Raw `$jsonSchema` fragments are passed through verbatim and aren't\n // re-checked on the read side (the server enforces them on write).\n};\n\nconst enumValidator: FieldValidator = (_deps, field, value, path, issues) => {\n const f = field as EnumField;\n if (!f.values.includes(value as never)) {\n push(\n issues,\n path,\n 'enum',\n `enum[${f.values.join(', ')}]`,\n `Value ${JSON.stringify(value)} is not in the allowed set`,\n );\n }\n};\n\nconst arrayValidator: FieldValidator = (deps, field, value, path, issues) => {\n const f = field as ArrayField;\n if (!Array.isArray(value)) {\n push(\n issues,\n path,\n 'type',\n `array<${f.items.kind}>`,\n `Expected array, got ${describeValue(value)}`,\n );\n return;\n }\n if (f.minItems !== undefined && value.length < f.minItems) {\n push(\n issues,\n path,\n 'constraint',\n `array(minItems ${f.minItems})`,\n `Length ${value.length} < ${f.minItems}`,\n );\n }\n if (f.maxItems !== undefined && value.length > f.maxItems) {\n push(\n issues,\n path,\n 'constraint',\n `array(maxItems ${f.maxItems})`,\n `Length ${value.length} > ${f.maxItems}`,\n );\n }\n if (f.uniqueItems) {\n const seen = new Set(\n value.map((item) =>\n item instanceof ObjectId\n ? item.toHexString()\n : typeof item === 'object' && item !== null\n ? JSON.stringify(item)\n : item,\n ),\n );\n if (seen.size !== value.length) {\n push(issues, path, 'constraint', 'array(uniqueItems)', 'Array contains duplicate items');\n }\n }\n value.forEach((item, i) => {\n deps.validateValue(f.items, item, `${path}[${i}]`, issues);\n });\n};\n\nconst objectValidator: FieldValidator = (deps, field, value, path, issues) => {\n const f = field as ObjectField;\n if (!isPlainObject(value)) {\n push(issues, path, 'type', 'object', `Expected object, got ${describeValue(value)}`);\n return;\n }\n deps.validateObjectProps(f, value as Document, path, issues, false);\n};\n\n/** Lookup table: field kind → validator. The single source of per-kind rules. */\nexport const FIELD_VALIDATORS: Record<SchemaType['kind'], FieldValidator> = {\n string: stringValidator,\n number: numberValidator,\n double: floatingValidator,\n long: floatingValidator,\n decimal: floatingValidator,\n boolean: booleanValidator,\n date: dateValidator,\n objectId: objectIdValidator,\n geoPoint: geoPointValidator,\n null: nullValidator,\n any: anyValidator,\n raw: rawValidator,\n enum: enumValidator,\n array: arrayValidator,\n object: objectValidator,\n};\n","/**\n * Drift-validation orchestrator: `validateValue` (dispatch to the per-kind\n * registry), `validateObjectProps` (declared properties + strict unknown-key\n * handling), and the public `validateDoc` entry point.\n *\n * Recursion between `validateValue` and `validateObjectProps` flows through the\n * `deps` object so neither this module nor `./field-validators.ts` imports the\n * other (no cycle).\n */\nimport type { Document } from 'mongodb';\nimport { ObjectId } from 'mongodb';\nimport { ORM_RESERVED_FIELDS } from '../to-mongo-schema.ts';\nimport type { ObjectField, SchemaType } from '../types.ts';\nimport { FIELD_VALIDATORS, type FieldValidatorDeps } from './field-validators.ts';\nimport { checkReservedValue, describeValue, push } from './helpers.ts';\nimport type { DriftIssue } from './types.ts';\n\n/** Validate a single value against its field schema, dispatching per kind. */\nfunction validateValue(\n field: SchemaType,\n value: unknown,\n path: string,\n issues: DriftIssue[],\n): void {\n const validator = FIELD_VALIDATORS[field.kind];\n if (validator) validator(deps, field, value, path, issues);\n}\n\n/** Validate an object's declared properties + strict unknown-key handling. */\nfunction validateObjectProps(\n field: ObjectField,\n value: Document,\n path: string,\n issues: DriftIssue[],\n topLevel: boolean,\n): void {\n const propPath = (key: string): string => (path ? `${path}.${key}` : key);\n\n for (const [key, prop] of Object.entries(field.properties)) {\n const present = key in value && value[key] !== undefined;\n if (!present) {\n if (!prop.flags.optional && !prop.flags.hasDefault) {\n push(issues, propPath(key), 'missing', prop.kind, `Required field \"${key}\" is missing`);\n }\n continue;\n }\n validateValue(prop, value[key], propPath(key), issues);\n }\n\n // Strict by default: mirror the validator's `additionalProperties: false`\n // unless the field opted out. The top level additionally allows the ORM's\n // reserved lifecycle fields (they are reserved in the $jsonSchema too).\n if (field.additionalProperties !== true) {\n const allowedReserved = topLevel ? ALLOWED_RESERVED_TOP : NO_RESERVED;\n for (const key of Object.keys(value)) {\n if (key in field.properties) continue;\n if (allowedReserved.has(key)) continue;\n push(\n issues,\n propPath(key),\n 'unknown_key',\n 'no additional properties',\n `Unexpected field \"${key}\"`,\n );\n }\n }\n\n const propCount = Object.keys(value).length;\n if (field.minProperties !== undefined && propCount < field.minProperties) {\n push(\n issues,\n path,\n 'constraint',\n `object(minProperties ${field.minProperties})`,\n `Has ${propCount} properties < ${field.minProperties}`,\n );\n }\n if (field.maxProperties !== undefined && propCount > field.maxProperties) {\n push(\n issues,\n path,\n 'constraint',\n `object(maxProperties ${field.maxProperties})`,\n `Has ${propCount} properties > ${field.maxProperties}`,\n );\n }\n\n // Type-check present-but-undeclared reserved lifecycle fields so drift in\n // `_id` / `__v` / `deletedAt` is surfaced too (mirrors toMongoSchema).\n if (topLevel) {\n if ('_id' in value && !('_id' in field.properties) && value._id !== undefined) {\n if (!(value._id instanceof ObjectId)) {\n push(issues, '_id', 'type', 'ObjectId', 'Reserved field \"_id\" must be ObjectId');\n }\n }\n for (const key of Object.keys(ORM_RESERVED_FIELDS)) {\n if (key in field.properties) continue;\n if (key in value && value[key] !== undefined) {\n checkReservedValue(key, value[key], key, issues);\n }\n }\n }\n}\n\n/** Recursive entry points shared by every validator (built after the functions above). */\nconst deps: FieldValidatorDeps = { validateValue, validateObjectProps };\n\n/**\n * Reserved top-level keys allowed under strict `additionalProperties`, hoisted\n * to module scope: allocating this Set per validated document was measurable\n * GC churn on the hot read path (drift defaults to 'report' — every uncached\n * read validates every document).\n */\nconst ALLOWED_RESERVED_TOP: ReadonlySet<string> = new Set([\n '_id',\n ...Object.keys(ORM_RESERVED_FIELDS),\n]);\nconst NO_RESERVED: ReadonlySet<string> = new Set<string>();\n\n/** Check a stored document against the declared schema; returns any drift issues. */\nexport const validateDoc = (schema: ObjectField, doc: Document): DriftIssue[] => {\n const issues: DriftIssue[] = [];\n if (doc === null || typeof doc !== 'object' || Array.isArray(doc)) {\n push(issues, '', 'type', 'object', `Expected a document object, got ${describeValue(doc)}`);\n return issues;\n }\n validateObjectProps(schema, doc, '', issues, true);\n return issues;\n};\n","/**\n * Logical → physical collection-name resolution.\n *\n * A collection is declared by a logical name; the physical name in MongoDB may\n * differ via a `collectionPrefix` (namespacing) or explicit per-collection\n * `collectionPhysicalNames` overrides. This module owns that mapping so the\n * rest of the ORM can always ask \"what physical name does this logical name\n * map to?\" via `createResolveCollectionName`.\n */\nexport const DEFAULT_COLLECTION_PREFIX_SEPARATOR = '-';\n/** Hard ceiling on MongoDB collection name length (server-enforced too). */\nexport const MAX_MONGODB_COLLECTION_NAME_BYTES = 255;\n\nexport interface ResolveCollectionConfig {\n /** Prepended to every physical name: `prefix + separator + logical`. */\n collectionPrefix?: string;\n /** Joins `collectionPrefix` and the logical name (default `-`). */\n collectionPrefixSeparator?: string;\n /** Per-logical-name physical overrides; wins over the prefix rule. */\n collectionPhysicalNames?: Partial<Record<string, string>>;\n}\n\n/**\n * Resolve a logical collection name → physical collection name.\n * - explicit `collectionPhysicalNames[logical]` wins\n * - otherwise `prefix + separator + logical`\n * - no prefix → identity\n */\nexport const createResolveCollectionName = (config: ResolveCollectionConfig) => {\n const sep = config.collectionPrefixSeparator ?? DEFAULT_COLLECTION_PREFIX_SEPARATOR;\n return (logical: string): string => {\n const override = config.collectionPhysicalNames?.[logical];\n if (override) return override;\n const prefix = config.collectionPrefix;\n if (!prefix) return logical;\n return `${prefix}${sep}${logical}`;\n };\n};\n","/**\n * Normalize a Mongo connection string so performance/reliability defaults are\n * explicit (mirrors sdk-db `normalizeMongoUrl`):\n * - retryWrites=false unless already set (keeps semantics predictable)\n * - w=1 unless another write concern is present\n * - directConnection=true ONLY for single-host, non-replica-set,\n * non-SRV URIs (`mongodb+srv` implies replica-set discovery — appending\n * `directConnection` there makes the driver reject the URI)\n *\n * Parsing is manual (string split + URLSearchParams) instead of WHATWG `new\n * URL`: the URL parser rejects multi-host seed lists (`h1:27017,h2:27017` —\n * it reads `,h2` as a port) and re-encodes userinfo/path in surprising ways.\n */\nexport const normalizeMongoUrl = (rawUrl: string): string => {\n try {\n const qIndex = rawUrl.indexOf('?');\n const base = qIndex === -1 ? rawUrl : rawUrl.slice(0, qIndex);\n const query = qIndex === -1 ? '' : rawUrl.slice(qIndex + 1);\n const params = new URLSearchParams(query);\n\n if (!params.has('retryWrites')) params.set('retryWrites', 'false');\n const hasWriteConcern =\n params.has('w') || params.has('wtimeoutMS') || params.has('writeConcern');\n if (!hasWriteConcern) params.set('w', '1');\n\n // Hosts live between '://' and the first '/' (userinfo may precede them,\n // separated by the LAST '@'). Commas separate seed-list members.\n const schemeSep = base.indexOf('://');\n const authority = schemeSep === -1 ? base : (base.slice(schemeSep + 3).split('/')[0] ?? '');\n const hostPart = authority.includes('@') ? (authority.split('@').pop() ?? '') : authority;\n const hostCount = hostPart === '' ? 0 : hostPart.split(',').length;\n const isSrv = base.startsWith('mongodb+srv://');\n if (!isSrv && hostCount === 1 && !params.has('replicaSet') && !params.has('directConnection')) {\n params.set('directConnection', 'true');\n }\n\n const queryString = params.toString();\n return queryString ? `${base}?${queryString}` : base;\n } catch {\n return rawUrl;\n }\n};\n","/**\n * Optional change-stream watchers that invalidate the shared query cache on\n * EXTERNAL writes — other processes, the raw `client` escape hatch, or direct\n * DB writes — closing the write-through-only gap of the ORM `QueryCache`.\n *\n * Requires a replica set / mongos. On standalone servers `$changeStream` is\n * rejected, so the invalidator logs a warning once and disables itself (the\n * cache then stays write-through only — see `MongoServiceConfig.cacheWatch`).\n *\n * One watcher is opened per unique (database, physical collection); any change\n * invalidates every cached read for that collection via\n * `QueryCache.invalidateByCollection`. Watchers self-heal: transient errors\n * retry with backoff and the collection is re-invalidated on reopen, so\n * changes missed during an outage don't leave stale entries behind.\n */\nimport type { ChangeStream, Db } from 'mongodb';\nimport type { QueryCache } from '../cache/query-cache.ts';\nimport { cacheCollectionKey } from '../cache/query-cache.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\nimport { sleepJittered } from '../utils/timeout.ts';\nimport { isPermanentWatchError } from '../utils/watch-errors.ts';\n\n/** A collection whose external writes should invalidate cached reads. */\nexport interface CacheInvalidationRef {\n /** Raw `Db` handle (e.g. `service.db.primaryClient.client`). */\n db: Db;\n /** PHYSICAL collection name — cache keys use it, so invalidation must too. */\n collection: string;\n}\n\nconst SEP = '\\u0000';\n\nexport class CacheInvalidator {\n private cache: QueryCache;\n private logger: LoggerLike;\n private streams = new Map<string, ChangeStream>();\n private disabled = false;\n private stopped = true;\n private warnedUnsupported = false;\n\n constructor(options: { cache: QueryCache; logger: LoggerLike }) {\n this.cache = options.cache;\n this.logger = options.logger;\n }\n\n /** Number of currently open change streams. */\n get size(): number {\n return this.streams.size;\n }\n\n /**\n * Open one watcher per unique (database, physical collection). Idempotent:\n * already-open streams are skipped; after `stop()` a later `start()` reopens.\n * Never throws — failures are logged (on unsupported servers it disables once).\n */\n async start(refs: CacheInvalidationRef[]): Promise<void> {\n if (this.disabled) return;\n this.stopped = false;\n const seen = new Set<string>();\n for (const ref of refs) {\n const key = `${ref.db.databaseName}${SEP}${ref.collection}`;\n if (seen.has(key) || this.streams.has(key)) continue;\n seen.add(key);\n // Never float as an unhandled rejection — an escape from the loop's\n // catch handler would crash the process.\n void this.watchLoop(key, ref).catch((err) => {\n this.logger.error?.(\n { error: err instanceof Error ? err.message : String(err), collection: ref.collection },\n 'cacheWatch: watcher crashed',\n );\n });\n }\n }\n\n /** Close every watcher. Safe to call repeatedly, and before any `start`. */\n async stop(): Promise<void> {\n this.stopped = true;\n const closes = [...this.streams.values()].map((stream) => {\n try {\n return Promise.resolve(stream.close()).catch(() => {});\n } catch {\n return Promise.resolve();\n }\n });\n this.streams.clear();\n await Promise.allSettled(closes);\n }\n\n private async watchLoop(key: string, ref: CacheInvalidationRef): Promise<void> {\n let backoff = 0;\n while (!this.stopped) {\n // A stream healthy for a long stretch before failing is an isolated\n // blip — reset escalation (backoff is for REPEATED failures).\n let connectedAt = Date.now();\n try {\n const stream = ref.db.collection(ref.collection).watch([]);\n // Prevent EventEmitter crashes between events; keep diagnostics.\n stream.on('error', (err) => {\n this.logger.debug?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'cacheWatch: stream error event',\n );\n });\n this.streams.set(key, stream);\n connectedAt = Date.now();\n if (backoff > 0) {\n // Reconnect after an outage: changes during the gap were missed, so\n // drop the collection's cache to force a re-fetch on the next read.\n this.cache.invalidateByCollection(\n cacheCollectionKey(ref.db.databaseName, ref.collection),\n );\n }\n const iterator = stream[Symbol.asyncIterator]();\n for await (const _change of iterator) {\n this.cache.invalidateByCollection(\n cacheCollectionKey(ref.db.databaseName, ref.collection),\n );\n }\n } catch (err) {\n if (Date.now() - connectedAt > 60_000) backoff = 0;\n const message = err instanceof Error ? err.message : String(err);\n const abandoned = this.streams.get(key);\n this.streams.delete(key);\n if (abandoned) {\n try {\n await abandoned.close();\n } catch {\n // Best-effort — the server drops the cursor on disconnect anyway.\n }\n }\n if (isPermanentWatchError(message)) {\n // Every collection shares the same server, so one permanent verdict\n // applies to all — disable once and stop retrying. NOTE: match ONLY\n // definitive permanent errors; replica errors like \"change stream\n // history lost\" (collection dropped) or resume-token expiry must stay\n // in the retry path.\n this.disabled = true;\n if (!this.warnedUnsupported) {\n this.warnedUnsupported = true;\n this.logger.warn?.(\n { collection: ref.collection, error: message },\n 'cacheWatch: change streams unavailable permanently — the query cache stays write-through only; set cache: { ttlMs } or disable cacheWatch',\n );\n }\n return;\n }\n if (this.stopped) return;\n this.logger.warn?.(\n { error: message, collection: ref.collection },\n 'cacheWatch: change stream error, retrying with backoff',\n );\n backoff = Math.min(backoff + 1000, 5000);\n await sleepJittered(backoff, 1000, true);\n }\n }\n }\n}\n","/**\n * Logger abstraction. The ORM never logs directly — it accepts any logger that\n * satisfies `LoggerLike` (pino, a console wrapper, a test stub, ...). This keeps\n * the package free of logging dependencies while remaining observability-agnostic.\n */\nexport interface LogFn {\n (obj: Record<string, unknown>, msg?: string): void;\n (msg: string): void;\n}\n\nexport interface LoggerLike {\n debug: LogFn;\n info: LogFn;\n warn: LogFn;\n error: LogFn;\n}\n\n/** A logger that swallows everything. Useful in tests / perf runs. */\nexport const createNoopLogger = (): LoggerLike => ({\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n});\n\nconst LEVELS = ['debug', 'info', 'warn', 'error'] as const;\nexport type LogLevel = (typeof LEVELS)[number];\n\nconst LEVEL_RANK: Record<LogLevel, number> = { debug: 10, info: 20, warn: 30, error: 40 };\n\nconst fmtObj = (obj: Record<string, unknown>): string => {\n try {\n return JSON.stringify(obj);\n } catch {\n return String(obj);\n }\n};\n\n/**\n * A tiny console logger matching the `LoggerLike` shape. `level` filters output.\n */\nexport const createConsoleLogger = (level: LogLevel = 'info'): LoggerLike => {\n const threshold = LEVEL_RANK[level];\n const make = (method: 'debug' | 'info' | 'warn' | 'error') => {\n const rank = LEVEL_RANK[method];\n const fn: LogFn = (a: unknown, b?: string) => {\n if (rank < threshold) return;\n const obj = typeof a === 'string' ? undefined : (a as Record<string, unknown>);\n const msg = typeof a === 'string' ? a : b;\n const prefix = obj !== undefined ? fmtObj(obj) : '';\n if (msg && prefix) {\n // eslint-disable-next-line no-console\n console[method](`[${method.toUpperCase()}]`, prefix, msg);\n } else {\n // eslint-disable-next-line no-console\n console[method](`[${method.toUpperCase()}]`, (msg ?? prefix) as string);\n }\n };\n return fn;\n };\n return {\n debug: make('debug'),\n info: make('info'),\n warn: make('warn'),\n error: make('error'),\n };\n};\n","/**\n * Service configuration: the `MongoServiceConfig` options type, cache policy\n * resolution (`resolveCache`), and runtime-config derivation\n * (`resolveRuntimeConfig`). Pure — no connection or manager wiring here, so the\n * config concerns of the service are isolated from the composition root.\n */\nimport { QueryCache, type QueryCacheOptions } from '../cache/query-cache.ts';\nimport type { DriftMode } from '../schema/validate-doc/index.ts';\nimport { createConsoleLogger, type LoggerLike } from '../utils/logger.ts';\n\n/**\n * Performance is ON by default. Resolve the service-level cache:\n * `undefined` → a default `QueryCache()`; `QueryCacheOptions` → constructed;\n * `QueryCache` → reused; `null` → disabled.\n */\nexport const resolveCache = (\n value: QueryCache | QueryCacheOptions | null | undefined,\n): QueryCache | undefined => {\n if (value === null) return undefined;\n if (value === undefined) return new QueryCache();\n if (value instanceof QueryCache) return value;\n return new QueryCache(value);\n};\n\nexport interface MongoServiceConfig {\n defaultDb?: string;\n migrationDir?: string;\n appName?: string;\n logger?: LoggerLike;\n /**\n * Map driver errors to typed DomainError/InfraError before rethrowing. ON by\n * default — set `false` to surface raw driver errors instead.\n */\n wrapMongoErrors?: boolean;\n /**\n * Read-through query cache shared by every CRUD read. ON by default:\n * `undefined` creates a default `QueryCache()`, `QueryCacheOptions` builds\n * one, a `QueryCache` is reused, and `null` disables caching.\n *\n * INVALIDATION: entries are dropped write-through — every ORM write\n * invalidates that collection's cached reads. External writers (other\n * processes, the raw `client` escape hatch, direct DB writes) do NOT\n * invalidate; with the default `ttlMs: 0` those reads stay stale\n * indefinitely, so multi-writer deployments should set `QueryCacheOptions.ttlMs`,\n * disable the cache, route latency-critical reads through the\n * change-stream aware `createHotCache()`, or set `cacheWatch: true`.\n */\n cache?: QueryCache | QueryCacheOptions | null;\n /**\n * Opt into change-stream invalidation of the shared query cache. When `true`\n * (and a cache is enabled), after `makeConnections()` one `$changeStream`\n * watcher is opened per registered collection; any write — including external\n * ones — invalidates that collection's cached reads. Requires a replica set /\n * mongos. On standalone servers the streams are rejected, a warning is logged\n * once, and invalidation silently disables (the cache stays write-through\n * only). Watchers self-heal across transient errors and are closed by\n * `closeConnections()`. Default: false.\n */\n cacheWatch?: boolean;\n /** Coalesce identical concurrent reads into one driver call. ON by default. */\n dedupeReads?: boolean;\n /**\n * Master performance switch. `perf: false` disables the query cache and\n * in-flight dedup even when the granular options are set. Defaults to true.\n */\n perf?: boolean;\n /**\n * Schema-drift policy for reads. When a document fetched from the DB\n * (cache-miss) doesn't match its declared schema:\n * - `'report'` (default) — log a warning with the offending fields, return as-is\n * - `'throw'` — throw `DomainError SCHEMA_DRIFT` (the document is never\n * cached or returned)\n * - `'off'` — no drift checking (previous behavior)\n * Detection-only: documents are never mutated. Projected/partial reads are\n * skipped. Overridable per op via `QueryOptions.drift`.\n */\n drift?: DriftMode;\n}\n\n/** The resolved, environment-merged runtime config shared by the whole service. */\nexport interface ResolvedServiceConfig {\n config: { defaultDb: string; migrationDir: string; appName: string };\n logger: LoggerLike;\n perfEnabled: boolean;\n sharedCache: QueryCache | undefined;\n dedupeReads: boolean;\n wrapMongoErrors: boolean;\n}\n\n/**\n * Merge `MongoServiceConfig` overrides with environment defaults and derive the\n * performance flags (cache/dedup/wrapMongoErrors). Called once by\n * `createMongoService`.\n */\nexport const resolveRuntimeConfig = (\n configOverrides: MongoServiceConfig,\n): ResolvedServiceConfig => {\n const config = {\n defaultDb: configOverrides.defaultDb ?? process.env.MONGO_URL ?? 'mongodb://localhost:27017/',\n migrationDir: configOverrides.migrationDir ?? process.env.MIGRATION_DIR ?? './migrations',\n appName: configOverrides.appName ?? process.env.APP_NAME ?? 'unknown-app',\n };\n const logger = configOverrides.logger ?? createConsoleLogger();\n // Perf is ON by default; `perf: false` (or the granular opt-outs) disable it.\n const perfEnabled = configOverrides.perf !== false;\n const sharedCache = perfEnabled ? resolveCache(configOverrides.cache) : undefined;\n const dedupeReads = perfEnabled ? (configOverrides.dedupeReads ?? true) : false;\n // Driver errors are mapped to typed DomainError/InfraError by default so a\n // framework can forward them to the client; `wrapMongoErrors: false` opts out.\n const wrapMongoErrors = configOverrides.wrapMongoErrors !== false;\n return { config, logger, perfEnabled, sharedCache, dedupeReads, wrapMongoErrors };\n};\n","import { MongoClient } from 'mongodb';\nimport type { DbClientsDefinition } from '../types.ts';\nimport { normalizeMongoUrl } from './connection-uri.ts';\n\nexport interface CoreConfigLike {\n defaultDb: string;\n}\n\n/**\n * Resolve the connection string for a client key:\n * 1. `dbClients[key].dbUrl` (normalized)\n * 2. env `DB_<CONSTANT_CASE_KEY>`\n * 3. `config.defaultDb`\n */\nexport const makeGetDbUrl =\n (dbClients: DbClientsDefinition, config: CoreConfigLike) =>\n (name: string): string => {\n const clientConfig = dbClients[name];\n if (clientConfig?.dbUrl) return normalizeMongoUrl(clientConfig.dbUrl);\n const envName = `DB_${name.replace(/[^a-zA-Z0-9]/g, '_').toUpperCase()}`;\n const envUrl = process.env[envName];\n if (envUrl) return normalizeMongoUrl(envUrl);\n return normalizeMongoUrl(config.defaultDb);\n };\n\n/**\n * Open one MongoClient per unique URL (clients sharing a URL share a pool),\n * then build a manager for each logical client. On any failure every client\n * opened *in this call* is closed and rolled back so no partial state remains.\n *\n * Connects are SINGLE-FLIGHT per URL: concurrent `makeConnections()` calls\n * await the same connect promise instead of each constructing a client (the\n * check-then-act alternative leaked the loser's socket pool forever — it was\n * registered in neither the pool nor the rollback list).\n */\nexport const makeConnectionFactory = <TClients extends DbClientsDefinition>(\n dbClients: TClients,\n db: Record<string, unknown>,\n getDbUrl: (name: string) => string,\n buildManager: (dbKey: string, dbName: string, client: MongoClient) => unknown,\n openedClients: Map<string, MongoClient> = new Map(),\n) => {\n /** In-progress connects by URL (cleared once settled). */\n const connecting = new Map<string, Promise<MongoClient>>();\n\n return async (names?: (keyof TClients & string)[]): Promise<void> => {\n const keys = (names && names.length > 0 ? names : Object.keys(dbClients)) as Array<\n keyof TClients & string\n >;\n const openedThisCall: Array<{ url: string; client: MongoClient }> = [];\n const assignedThisCall: string[] = [];\n\n try {\n for (const key of keys) {\n const definition = dbClients[key]!;\n const dbUrl = getDbUrl(key);\n let client = openedClients.get(dbUrl);\n if (!client) {\n const inflight = connecting.get(dbUrl);\n if (inflight) {\n // Another concurrent call is already connecting this URL — share it.\n client = await inflight;\n } else {\n const attempt = (async () => {\n const c = new MongoClient(dbUrl, {\n connectTimeoutMS: definition.connectTimeoutMs ?? 10_000,\n serverSelectionTimeoutMS: definition.connectTimeoutMs ?? 10_000,\n ...(definition.readPreference && { readPreference: definition.readPreference }),\n ...(definition.readConcern && { readConcern: definition.readConcern }),\n ...(definition.writeConcern && { writeConcern: definition.writeConcern }),\n });\n // Swallow driver-level 'error' events (e.g. connection\n // interruption during close) so they never surface as unhandled\n // rejections. Topology failures still reject in-flight ops.\n c.on('error', () => {});\n await c.connect();\n return c;\n })();\n connecting.set(dbUrl, attempt);\n try {\n client = await attempt;\n openedClients.set(dbUrl, client);\n openedThisCall.push({ url: dbUrl, client });\n } finally {\n connecting.delete(dbUrl);\n }\n }\n }\n const dbKey = `${key}Client`;\n db[dbKey] = buildManager(key, definition.name, client);\n assignedThisCall.push(dbKey);\n }\n } catch (err) {\n await Promise.allSettled(openedThisCall.map(({ client }) => client.close()));\n for (const { url } of openedThisCall) openedClients.delete(url);\n // Remove managers assigned earlier in this call so `db` never holds a\n // handle whose MongoClient was just closed (dangling manager on partial\n // failure — the next makeConnections overwrites them anyway).\n for (const dbKey of assignedThisCall) delete db[dbKey];\n throw err;\n }\n };\n};\n\n/** Close every pooled client and clear the pool. Never throws — each close is\n * guarded against both sync throws and rejections (the driver can throw a\n * `MongoClientClosedError` when a connection is still checked out at close). */\nexport const closeConnections = async (openedClients: Map<string, MongoClient>): Promise<void> => {\n const closes = [...openedClients.values()].map((client) => {\n try {\n return Promise.resolve(client.close()).catch(() => {});\n } catch {\n return Promise.resolve();\n }\n });\n await Promise.allSettled(closes);\n openedClients.clear();\n};\n","/**\n * Health check: pings every connected manager's raw `Db` handle in parallel\n * (with a configurable timeout per ping, default 2s) and reports per-DB latency,\n * failure reasons + overall status. Types and implementation live together here\n * so `service/index.ts` stays a thin composition root.\n */\nimport type { Db } from 'mongodb';\nimport { withTimeout } from '../utils/timeout.ts';\n\nexport interface DbHealthResult {\n /** Logical db client key (e.g. `primary`). */\n name: string;\n ok: boolean;\n /** Ping round-trip time in ms (present when `ok`). */\n latencyMs?: number;\n /** Why the ping failed — timeout vs auth vs network (present when `!ok`). */\n error?: string;\n}\n\nexport interface HealthReport {\n /**\n * Overall status. `false` when ANY db fails — including the degenerate\n * \"no dbs connected\" case (an empty manager record is NOT healthy).\n */\n ok: boolean;\n /** Total elapsed time across all pings in ms. */\n latencyMs: number;\n dbs: DbHealthResult[];\n}\n\n/** Build a `health()` implementation over the service's manager record. */\nexport const createHealth =\n (db: Record<string, unknown>, options: { timeoutMs?: number } = {}) =>\n async (): Promise<HealthReport> => {\n const started = performance.now();\n const timeoutMs = options.timeoutMs ?? 2_000;\n const dbs = await Promise.all(\n Object.entries(db).map(async ([key, manager]): Promise<DbHealthResult> => {\n const name = key.replace(/Client$/, '');\n const handle = (manager as { client?: Db } | undefined)?.client;\n if (!handle) return { name, ok: false, error: 'no client handle on manager' };\n try {\n const t0 = performance.now();\n await withTimeout(handle.admin().command({ ping: 1 }), timeoutMs, `health:${name}`);\n return { name, ok: true, latencyMs: performance.now() - t0 };\n } catch (err) {\n // Keep the WHY (timeout/auth/DNS collapse into the same boolean\n // otherwise and operators can't triage). Message only — no stacks.\n return {\n name,\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }),\n );\n return {\n ok: dbs.length > 0 && dbs.every((r) => r.ok),\n latencyMs: performance.now() - started,\n dbs,\n };\n };\n","import type { Document, Filter } from 'mongodb';\nimport { canonicalKey, DataLoader } from '../loader/dataloader.ts';\nimport type { RelationDef } from './relation.ts';\n\nexport interface PopulateDeps {\n /** Fetch docs from a (logical) collection by filter. */\n findMany: (\n collection: string,\n filter: Filter<Document>,\n options?: { projection?: Document; limit?: number },\n ) => Promise<Document[]>;\n}\n\nexport interface PopulateOptions {\n maxBatchSize?: number;\n cache?: boolean;\n /**\n * Cap on docs fetched per foreign-key batch (default 10_000). A `hasMany` /\n * `manyToMany` relation with more children than this is silently truncated —\n * raise the cap when you expect larger joins.\n */\n maxDocs?: number;\n}\n\n/**\n * Batch + cache loader for one foreign key path. `$in`-queries one foreign\n * collection per relation (regardless of how many source docs reference it),\n * which is what turns N+1 population into 1+N.\n */\nconst createForeignKeyLoader = (\n deps: PopulateDeps,\n collection: string,\n foreignField: string,\n options: PopulateOptions = {},\n): DataLoader<unknown, Document[]> =>\n new DataLoader<unknown, Document[]>({\n ...(options.maxBatchSize !== undefined ? { maxBatchSize: options.maxBatchSize } : {}),\n ...(options.cache !== undefined ? { cache: options.cache } : {}),\n keyOf: canonicalKey,\n batch: async (keys) => {\n const docs = await deps.findMany(\n collection,\n { [foreignField]: { $in: keys } },\n {\n ...(options.maxDocs !== undefined ? { limit: options.maxDocs } : {}),\n },\n );\n // Index foreign docs by canonical key value so distinct-but-equal keys\n // (e.g. two ObjectId instances with the same hex) resolve correctly.\n const index = new Map<string, Document[]>();\n for (const doc of docs) {\n const value = (doc as Document)[foreignField];\n const canonical = canonicalKey(value);\n const bucket = index.get(canonical) ?? [];\n bucket.push(doc);\n index.set(canonical, bucket);\n }\n const map = new Map<unknown, Document[]>();\n for (const key of keys) {\n map.set(key, index.get(canonicalKey(key)) ?? []);\n }\n return map;\n },\n });\n\nconst distinctKeys = (values: unknown[]): unknown[] => {\n const seen = new Set<string>();\n const out: unknown[] = [];\n for (const value of values) {\n if (value === undefined || value === null) continue;\n const canonical = canonicalKey(value);\n if (!seen.has(canonical)) {\n seen.add(canonical);\n out.push(value);\n }\n }\n return out;\n};\n\n/**\n * Resolve relations on an array of documents using DataLoader-batched queries.\n * Source documents are COPIED (shallow) before joining — populating a result\n * set that came from the shared query cache must never mutate the cached\n * entry (a cached order would otherwise carry join data into every later\n * reader of that cache entry). Returns the copies typed with joined fields.\n *\n * Independent relations resolve concurrently; relations sharing a target\n * collection + foreign field share ONE DataLoader batch.\n *\n * const orders = await users.findMany('orders', { userId });\n * const [withCustomer] = ... // orders[i].customer is now the joined Customer document\n * const populated = await populate(orders, [\n * belongsTo({ collection: 'customers', localField: 'customerId', as: 'customer' }),\n * ]);\n */\nexport const makePopulator = (deps: PopulateDeps) => {\n const populate = async <T extends Document>(\n docs: T[],\n relations: RelationDef[],\n options: PopulateOptions = {},\n ): Promise<Array<T & Record<string, unknown>>> => {\n // Copy-on-write: attach joins onto fresh copies so shared/cached\n // documents are never polluted (see module doc).\n const out = docs.map((doc) => ({ ...doc })) as Array<T & Record<string, unknown>>;\n if (out.length === 0 || relations.length === 0) return out;\n\n // One loader per (collection, foreignField) per call: two relations\n // targeting the same collection share a single `$in` batch instead of\n // issuing duplicate queries.\n const loaderCache = new Map<string, DataLoader<unknown, Document[]>>();\n const loaderFor = (\n collection: string,\n foreignField: string,\n ): DataLoader<unknown, Document[]> => {\n const cacheKey = `${collection}\\u0000${foreignField}`;\n let loader = loaderCache.get(cacheKey);\n if (!loader) {\n loader = createForeignKeyLoader(deps, collection, foreignField, options);\n loaderCache.set(cacheKey, loader);\n }\n return loader;\n };\n\n /** Load + index foreign docs for one hop: canonical key → matching docs. */\n const loadIndex = async (\n collection: string,\n foreignField: string,\n keys: unknown[],\n ): Promise<Map<string, Document[]>> => {\n const values = await loaderFor(collection, foreignField).loadMany(keys);\n const byKey = new Map<string, Document[]>();\n keys.forEach((key, i) => {\n byKey.set(canonicalKey(key), (values[i] as Document[] | undefined) ?? []);\n });\n return byKey;\n };\n\n await Promise.all(\n relations.map(async (relation) => {\n const target = relation.foreignField ?? '_id';\n const sourceKeys = distinctKeys(out.map((doc) => (doc as Document)[relation.localField]));\n\n if (relation.type === 'belongsTo') {\n const byKey = await loadIndex(relation.collection, target, sourceKeys);\n for (const doc of out) {\n const key = (doc as Document)[relation.localField];\n const matches =\n key === undefined || key === null ? undefined : byKey.get(canonicalKey(key));\n (doc as Record<string, unknown>)[relation.as] =\n matches?.[0] ?? (relation.optional ? undefined : null);\n }\n } else if (relation.type === 'hasMany') {\n const byKey = await loadIndex(relation.collection, target, sourceKeys);\n for (const doc of out) {\n const key = (doc as Document)[relation.localField];\n (doc as Record<string, unknown>)[relation.as] =\n key === undefined || key === null ? [] : (byKey.get(canonicalKey(key)) ?? []);\n }\n } else {\n // manyToMany: source → join docs → target docs (two batched hops).\n const throughByKey = await loadIndex(\n relation.through.collection,\n relation.through.localField,\n sourceKeys,\n );\n const joinDocs = [...throughByKey.values()].flat();\n const targetKeys = distinctKeys(\n joinDocs.map((join) => (join as Document)[relation.through.foreignField]),\n );\n const targetByKey = await loadIndex(relation.collection, target, targetKeys);\n\n for (const doc of out) {\n const key = (doc as Document)[relation.localField];\n const joins =\n key === undefined || key === null ? [] : (throughByKey.get(canonicalKey(key)) ?? []);\n // Dedupe targets: duplicate pivot rows pointing at the same\n // target must not repeat it in the populated array.\n const seenTargets = new Set<string>();\n const targets: Document[] = [];\n for (const join of joins) {\n const tk = canonicalKey((join as Document)[relation.through.foreignField]);\n if (seenTargets.has(tk)) continue;\n seenTargets.add(tk);\n const bucket = targetByKey.get(tk);\n if (bucket) targets.push(...bucket);\n }\n (doc as Record<string, unknown>)[relation.as] = targets;\n }\n }\n }),\n );\n return out;\n };\n\n return { populate };\n};\n\nexport type Populator = ReturnType<typeof makePopulator>;\n","import type { ReadConcernLike, ReadPreferenceLike, WriteConcern } from 'mongodb';\nimport type { HookMap } from './hooks/hooks.ts';\nimport type { InferDoc } from './schema/infer.ts';\nimport type { ObjectField } from './schema/types.ts';\n\n/** A Mongo index definition usable by `createIndexes`. */\nexport interface IndexSpec {\n key: Record<string, 1 | -1 | 'text' | 'hashed' | '2dsphere'>;\n options?: {\n name?: string;\n unique?: boolean;\n sparse?: boolean;\n expireAfterSeconds?: number;\n };\n}\n\n/** Auto-timestamp field names maintained by the ORM when `timestamps` is set. */\nexport interface CollectionTimestamps {\n /** Field stamped with the creation time on insert (default `createdAt`). */\n createdAt?: string;\n /** Field stamped with the modification time on every update (default `updatedAt`). */\n updatedAt?: string;\n}\n\n/**\n * Collection definition. A value of `collections` may be either a raw object\n * schema (`s.object({...})`) or a `CollectionDefinition` carrying optional\n * indexes + hooks.\n */\nexport interface CollectionDefinition<TSchema extends ObjectField = ObjectField> {\n schema: TSchema;\n indexes?: IndexSpec[];\n hooks?: HookMap<InferDoc<TSchema>>;\n /**\n * Auto-maintain timestamps on create/update. `true` uses the defaults\n * (`createdAt`/`updatedAt`); an object names custom fields. Fields must exist\n * in the schema for the values to be stamped.\n */\n timestamps?: CollectionTimestamps | boolean;\n}\n\nexport type CollectionLike = CollectionDefinition<any> | ObjectField;\n\n/**\n * One logical Mongo database. Keys of `collections` are the *logical* collection\n * names used in every ORM call; physical names are derived via\n * `collectionPrefix` / `collectionPhysicalNames`.\n */\nexport interface DBClientDefinition<\n TCollections extends Record<string, CollectionLike> = Record<string, CollectionLike>,\n> {\n /** Actual MongoDB database name. */\n name: string;\n /** Connection string. Falls back to env `DB_<CONSTANT_CASE_KEY>`, then config.defaultDb. */\n dbUrl?: string;\n collections: TCollections;\n /** Prefix applied to every logical collection name to produce the physical name. */\n collectionPrefix?: string;\n collectionPrefixSeparator?: string;\n /** Per-logical-collection physical-name overrides. */\n collectionPhysicalNames?: Partial<Record<string, string>>;\n connectTimeoutMs?: number;\n readPreference?: ReadPreferenceLike;\n readConcern?: ReadConcernLike;\n writeConcern?: WriteConcern;\n}\n\nexport type DbClientsDefinition = Record<\n string,\n DBClientDefinition<Record<string, CollectionLike>>\n>;\n\n/* ------------------------------------------------------------------ *\n * Schema-first type inference. Call sites never pass `<TDoc>` —\n * the collection-name literal derives the document type automatically.\n * ------------------------------------------------------------------ */\n\nexport type NormalizeCollection<T> = T extends { kind: 'object' }\n ? { schema: T }\n : T extends CollectionDefinition\n ? T\n : never;\n\nexport type CollectionSchema<T> =\n T extends CollectionDefinition<infer S> ? S : T extends ObjectField ? T : never;\n\nexport type CollectionDoc<T> =\n T extends CollectionDefinition<infer S>\n ? InferDoc<S>\n : T extends ObjectField\n ? InferDoc<T>\n : never;\n\nexport type ExtractDbNames<TClients extends DbClientsDefinition> = keyof TClients & string;\n\nexport type ExtractCollectionNames<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> = keyof TClients[TDb]['collections'] & string;\n\nexport type ExtractCollectionType<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n TCollection extends ExtractCollectionNames<TClients, TDb>,\n> = CollectionDoc<TClients[TDb]['collections'][TCollection]>;\n\n/** Runtime normalization: schema-or-definition → `{ schema, indexes, hooks, timestamps }`. */\nexport const asCollectionDefinition = (\n value: CollectionLike,\n): {\n schema: ObjectField;\n indexes: IndexSpec[];\n hooks: HookMap;\n timestamps?: CollectionTimestamps;\n} => {\n if (value && typeof value === 'object' && 'schema' in value) {\n const def = value as CollectionDefinition;\n const ts = def.timestamps;\n const timestamps =\n ts === true\n ? { createdAt: 'createdAt', updatedAt: 'updatedAt' }\n : ts && typeof ts === 'object'\n ? ts\n : undefined;\n return {\n schema: def.schema,\n indexes: def.indexes ?? [],\n hooks: def.hooks ?? {},\n ...(timestamps ? { timestamps } : {}),\n };\n }\n return { schema: value as ObjectField, indexes: [], hooks: {} };\n};\n","import { mapMongoDriverError } from '../errors/index.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\n\n/** Structured metadata attached to every logged DB operation. */\nexport interface DbOpMeta {\n collection: string;\n physicalCollection?: string;\n db: string;\n op: string;\n /**\n * What was sent to the database (filter / document / update / pipeline /\n * options). Surfaced in the ignex debugbar as the span's `params`, so the\n * dashboard shows exactly what the query carried — not just its name.\n * Optional: ops without a payload worth showing omit it.\n */\n params?: unknown;\n}\n\nexport interface TraceDbOpOptions {\n /** Map driver errors to typed DomainError/InfraError before rethrowing. */\n wrapMongoErrors?: boolean;\n /**\n * Test/advanced seam: inject the ignex-debugbar `debugQuery` implementation\n * directly. Omitted (production) → probed lazily via `@ignex/core/debug`.\n * `null` forces the plain pass-through without touching the probe cache.\n */\n debugQuery?: DebugQuery | null;\n}\n\n/**\n * The ignex-debugbar `debugQuery` free helper (`@ignex/core/debug`), resolved\n * lazily so the ORM stays standalone: `undefined` until probed, `null` when\n * `@ignex/core` is not installed (plain ORM usage), the function otherwise.\n * `debugQuery` itself is a zero-cost pass-through when no request trace is\n * active, so production ignex apps pay nothing either.\n */\ntype DebugQuery = (\n sql: string,\n params: unknown,\n fn: () => unknown | Promise<unknown>,\n) => Promise<unknown>;\n\nlet debugQueryCache: DebugQuery | null | undefined;\n\n/** Probe once per process; the failed dynamic import is caught and cached. */\nconst probeDebugQuery = async (): Promise<void> => {\n if (debugQueryCache !== undefined) return;\n try {\n const mod = (await import('@ignex/core/debug')) as { debugQuery?: DebugQuery };\n debugQueryCache = typeof mod.debugQuery === 'function' ? mod.debugQuery : null;\n } catch {\n debugQueryCache = null;\n }\n};\n\n/**\n * Make a captured param payload JSON-safe before it reaches the debugbar: a\n * JSON round-trip strips `undefined` keys, RegExps, class instances and other\n * values that would otherwise crash `JSON.stringify` downstream (the live API\n * and the SQLite history both serialize span attrs). Mongo filters may carry\n * such values (`_id` ObjectIds serialize to their hex string; Dates to ISO\n * strings — exactly what a developer wants to see). Falls back to `String()`\n * when even the round-trip fails.\n */\nconst sanitizeDebugParams = (value: unknown): unknown => {\n try {\n return JSON.parse(JSON.stringify(value));\n } catch {\n try {\n return String(value);\n } catch {\n return '[unserializable]';\n }\n }\n};\n\n/**\n * Wrap a DB operation with start/ok/error structured logging (duration, op,\n * collection, db). When `wrapMongoErrors` is set, driver errors are mapped to\n * the ORM's typed error classes before being rethrown.\n *\n * When the app runs inside ignex with the debugbar enabled, every operation\n * is ALSO recorded as a `db` span in the current request's trace (`kind:\n * \"db\"`) — it shows up in the debugbar waterfall, the Queries tab and the\n * per-request db-time aggregate. The integration is optional and automatic:\n * it activates only when `@ignex/core` is installed AND a request trace is\n * active, and costs a single cached module probe otherwise.\n *\n * Caveat: the hook only fires when the dynamic `@ignex/core/debug` probe\n * resolves to the SAME module instance as the app's debugbar plugin (the\n * plugin's tracer gates on its own `tracingEnabled`). That is the case for a\n * normal npm install of both packages — but if this ORM is `bun link`-ed into\n * an app whose build cannot resolve `@ignex/core/debug` from the linked path,\n * the bundler externalizes the probe and it silently no-ops (no `db` spans).\n * Install `@ignex/core` alongside the app (npm-style) to keep the integration.\n */\nexport const traceDbOp = async <T>(\n logger: LoggerLike,\n meta: DbOpMeta,\n fn: () => T | Promise<T>,\n options: TraceDbOpOptions = {},\n): Promise<T> => {\n const start = performance.now();\n logger.debug({ ...meta, operation: 'start' }, 'start');\n try {\n // First op only: resolve the optional ignex-debugbar hook. An explicitly\n // injected `options.debugQuery` (tests / advanced hosts) wins over the\n // lazily-probed `@ignex/core/debug` helper.\n let debugQuery = options.debugQuery;\n if (debugQuery === undefined) {\n if (debugQueryCache === undefined) await probeDebugQuery();\n debugQuery = debugQueryCache;\n }\n // Pass WHAT WAS SENT (filter/doc/pipeline/…) as the span's params so the\n // debugbar shows the actual query payload, not just `collection.op`.\n const params = meta.params === undefined ? undefined : sanitizeDebugParams(meta.params);\n const result = debugQuery\n ? ((await debugQuery(`${meta.collection}.${meta.op}`, params, () => fn())) as T)\n : await fn();\n const durationMs = performance.now() - start;\n logger.info({ ...meta, durationMs }, 'ok');\n return result;\n } catch (err) {\n const durationMs = performance.now() - start;\n const loggable =\n err instanceof Error\n ? { name: err.name, message: err.message, code: (err as { code?: unknown }).code }\n : err;\n logger.error({ ...meta, durationMs, error: loggable }, 'error');\n if (options.wrapMongoErrors) throw mapMongoDriverError(err, meta);\n throw err;\n }\n};\n","/**\n * Shared op-pipeline deps for the `make*Ops` factories.\n *\n * Every op factory (`crud`, `pagination`, `aggregation`) used to hand-build the\n * same `{ trace, meta }` pair: structured start/ok/error logging + op metadata.\n * This module builds that pair once from `(logger, dbLabel, resolve,\n * wrapMongoErrors)` so the boilerplate lives in exactly one place.\n */\nimport type { LoggerLike } from '../utils/logger.ts';\nimport type { DbOpMeta } from './trace-db-op.ts';\nimport { traceDbOp } from './trace-db-op.ts';\n\nexport interface OpDeps<TC> {\n /** Log a start/ok/error trace around one DB call (optional driver-error mapping). */\n trace: <T>(meta: DbOpMeta, fn: () => T | Promise<T>) => Promise<T>;\n /** Structured log metadata for a (collection, op) + optional sent-payload. */\n meta: (collection: TC, op: string, params?: unknown) => DbOpMeta;\n}\n\n/** Build the `{ trace, meta }` op-pipeline deps shared by every op factory. */\nexport const makeOpDeps = <TC>(\n logger: LoggerLike,\n dbLabel: string,\n resolve: (logical: string) => string,\n wrapMongoErrors: boolean,\n): OpDeps<TC> => {\n const trace = <T>(meta: DbOpMeta, fn: () => T | Promise<T>): Promise<T> =>\n traceDbOp(logger, meta, fn, { wrapMongoErrors });\n const meta = (collection: TC, op: string, params?: unknown): DbOpMeta => ({\n collection: String(collection),\n physicalCollection: resolve(String(collection)),\n db: dbLabel,\n op,\n ...(params !== undefined ? { params } : {}),\n });\n return { trace, meta };\n};\n","import type {\n ClientSession,\n CollationOptions,\n Document,\n Hint,\n ReadConcern,\n ReadPreferenceLike,\n WriteConcern,\n} from 'mongodb';\nimport type { DriftMode } from '../schema/validate-doc/index.ts';\n\n/**\n * SDK-level query options. These are separated from driver options so the\n * public API surface stays stable against driver changes. `resolveQueryOptions`\n * strips them out and forwards the remainder untouched to the driver.\n */\nexport interface QueryOptions {\n session?: ClientSession;\n maxTimeMS?: number;\n hint?: Hint;\n /** Retry attempts for transient errors (default 3). */\n maxAttempts?: number;\n /** Base retry backoff in ms (default 150, exponential). */\n retryDelayMs?: number;\n batchSize?: number;\n /**\n * Per-op in-flight dedup override. `true` forces dedup on, `false` forces it\n * off (even when the service default is on); unset inherits the service\n * `dedupeReads` default.\n */\n dedupe?: boolean;\n /** Per-op read-cache bypass. `false` skips the cache for this read. */\n cache?: boolean;\n /**\n * Per-op write-retry override. Reads always retry transient errors; writes\n * retry ONLY when `retryWrites: true` (retrying a write is at-least-once —\n * a committed write whose ack was lost would be re-executed, so enable only\n * for idempotent writes). Default: off for write ops.\n */\n /**\n * Per-op write-retry override. Reads always retry transient errors; writes\n * retry ONLY when `retryWrites: true` (retrying a write is at-least-once —\n * a committed write whose ack was lost would be re-executed, so enable only\n * for idempotent writes). Default: off for write ops.\n */\n retryWrites?: boolean;\n /**\n * Per-op schema-drift policy override for reads (see `MongoServiceConfig.drift`).\n * `true` → `'throw'`, `false` → `'off'`, or an explicit `DriftMode` string.\n * Unset inherits the service-level default (`'report'`). Only checked when a\n * document is fetched from the DB (cache-miss); projected/partial reads are\n * skipped.\n */\n drift?: DriftMode | boolean;\n /** Driver-level options forwarded untouched to the underlying call. */\n collation?: CollationOptions;\n readPreference?: ReadPreferenceLike;\n readConcern?: ReadConcern;\n writeConcern?: WriteConcern;\n comment?: string | Document;\n let?: Document;\n timeoutMS?: number;\n}\n\nexport interface ResolvedQueryOptions<TDriverOpts = Record<string, unknown>> {\n maxAttempts: number;\n retryDelayMs: number;\n /** Tri-state: `undefined` inherits the service-level default. */\n dedupe?: boolean;\n /** Tri-state: `undefined` inherits the service-level default. */\n cache?: boolean;\n /** Write ops retry transient errors only when this is `true`. */\n retryWrites?: boolean;\n sdk: {\n session?: ClientSession;\n maxTimeMS?: number;\n hint?: Hint;\n batchSize?: number;\n drift?: DriftMode | boolean;\n };\n driverOpts: TDriverOpts;\n}\n\nexport const resolveQueryOptions = <T extends QueryOptions>(\n options?: T,\n): ResolvedQueryOptions<Omit<T, keyof QueryOptions>> => {\n // Clamp to >= 1 so `maxAttempts: 0` (a common \"disable retry\" attempt) can\n // never reach `withRetry` and produce a `throw undefined`.\n const maxAttempts = Math.max(1, options?.maxAttempts ?? 3);\n const retryDelayMs = options?.retryDelayMs ?? 150;\n const {\n session,\n maxTimeMS,\n hint,\n batchSize,\n drift,\n maxAttempts: _ma,\n retryDelayMs: _rd,\n dedupe,\n cache,\n retryWrites,\n ...rest\n } = options ?? {};\n return {\n maxAttempts,\n retryDelayMs,\n ...(dedupe !== undefined ? { dedupe } : {}),\n ...(cache !== undefined ? { cache } : {}),\n ...(retryWrites !== undefined ? { retryWrites } : {}),\n sdk: {\n ...(session !== undefined ? { session } : {}),\n ...(maxTimeMS !== undefined ? { maxTimeMS } : {}),\n ...(hint !== undefined ? { hint } : {}),\n ...(batchSize !== undefined ? { batchSize } : {}),\n ...(drift !== undefined ? { drift } : {}),\n },\n driverOpts: rest as Omit<T, keyof QueryOptions>,\n };\n};\n\n/** Build driver option objects omitting undefined SDK fields (exactOptionalPropertyTypes). */\nexport const pickSdkOptions = (sdk: {\n session?: unknown;\n maxTimeMS?: unknown;\n hint?: unknown;\n batchSize?: unknown;\n drift?: unknown;\n}): Record<string, unknown> => ({\n ...(sdk.session !== undefined ? { session: sdk.session } : {}),\n ...(sdk.maxTimeMS !== undefined ? { maxTimeMS: sdk.maxTimeMS } : {}),\n ...(sdk.hint !== undefined ? { hint: sdk.hint } : {}),\n ...(sdk.batchSize !== undefined ? { batchSize: sdk.batchSize } : {}),\n ...(sdk.drift !== undefined ? { drift: sdk.drift } : {}),\n});\n\n/**\n * Resolve the effective drift mode for a read: per-op override wins, then the\n * service default, else `'report'`.\n */\nexport const resolveDriftMode = (\n perOp: DriftMode | boolean | undefined,\n serviceDefault: DriftMode | undefined,\n): DriftMode => {\n if (perOp === true) return 'throw';\n if (perOp === false) return 'off';\n if (perOp === 'off' || perOp === 'report' || perOp === 'throw') return perOp;\n return serviceDefault ?? 'report';\n};\n","import { withRetry } from '../mongo-helpers.ts';\nimport {\n type QueryOptions,\n type ResolvedQueryOptions,\n resolveQueryOptions,\n} from './query-options.ts';\nimport type { DbOpMeta } from './trace-db-op.ts';\n\nexport interface CrudOpDeps<TCollection> {\n trace: <T>(meta: DbOpMeta, fn: () => T | Promise<T>) => Promise<T>;\n meta: (collection: TCollection, op: string, params?: unknown) => DbOpMeta;\n}\n\n/**\n * The uniform op wrapper every CRUD method funnels through:\n * resolve SDK options → trace (structured logs) → retry on transient errors.\n *\n * `execute` receives the resolved options so methods only declare the driver\n * options they forward.\n */\nexport const defineCrudOp = async <TCollection, TResult>(\n deps: CrudOpDeps<TCollection>,\n collection: TCollection,\n opName: string,\n execute: (resolved: ResolvedQueryOptions) => TResult | Promise<TResult>,\n options?: QueryOptions,\n write = false,\n /** What was sent to the DB (filter/doc/pipeline) — recorded in the debugbar. */\n params?: unknown,\n): Promise<TResult> => {\n const resolved = resolveQueryOptions(options);\n // Writes are at-least-once: retry them only when the caller opts in via\n // `retryWrites: true`. Reads are idempotent and always retried.\n const maxAttempts = write && resolved.retryWrites !== true ? 1 : resolved.maxAttempts;\n return deps.trace(deps.meta(collection, opName, params), async () =>\n withRetry(async () => execute(resolved), {\n maxAttempts,\n delayMs: resolved.retryDelayMs,\n }),\n );\n};\n","/**\n * Fully type-safe, chainable aggregation pipeline builder.\n *\n * Every stage is typed against the current document shape, so intellisense\n * follows the real schema fields and the result type of `.toArray()` /\n * `.first()` is inferred through the whole chain. `$lookup` sub-pipelines are\n * scoped to the related collection's schema and `$facet` branches get their own\n * typed sub-builder — see `src/service/pipeline-types.ts` for the type model.\n *\n * const top = await db.pipeline('orders')\n * .match({ status: 'paid' })\n * .group({ _id: '$userId', total: { $sum: '$total' } })\n * .sort({ total: -1 })\n * .limit(3)\n * .toArray();\n */\nimport type {\n AggregateOptions,\n AggregationCursor,\n ClientSession,\n Collection,\n Document,\n Hint,\n} from 'mongodb';\nimport { BadRequest } from '../errors/index.ts';\nimport type { FilterInput } from '../shared/filter-types.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../types.ts';\nimport type { CachedAggregate } from './aggregation/types.ts';\nimport { type CrudOpDeps, defineCrudOp } from './crud-op.ts';\nimport type {\n Added,\n FacetOutput,\n FacetSpec,\n ForeignDocOf,\n GeoNearOutput,\n GeoNearSpec,\n Grouped,\n GroupSpec,\n LookupJoinedFor,\n LookupSpecFor,\n Projected,\n Projection,\n SortKeys,\n Unsetted,\n UnwindSpec,\n Unwound,\n} from './pipeline-types.ts';\nimport type { QueryOptions, ResolvedQueryOptions } from './query-options.ts';\n\n/** Execution dependencies wired up by `makeAggregationOps`. */\nexport interface PipelineBuilderDeps {\n logical: string;\n coll: () => Collection<Document>;\n crudDeps: CrudOpDeps<string>;\n mergeDriver: (\n driverOpts: Record<string, unknown>,\n sdk: { session?: ClientSession; maxTimeMS?: number; hint?: Hint },\n ) => AggregateOptions;\n options?: AggregateOptions & QueryOptions;\n /**\n * Cached-aggregation runner (write-through cache + dedup). Present on real\n * builders so `.toArray()` / `.first()` are cached; absent on stage-only\n * builders (sub-pipelines read via `.raw()` and never execute).\n */\n cachedAggregate?: CachedAggregate;\n}\n\nexport class PipelineBuilder<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n TDoc extends Document,\n> {\n constructor(\n private readonly deps: PipelineBuilderDeps,\n private readonly stages: Document[] = [],\n ) {}\n\n /** Raw accumulated stages — embeddable into `$lookup` / `$facet` branches. */\n raw(): Document[] {\n return this.stages;\n }\n\n private assertNonNegativeFinite(name: string, n: number): void {\n if (!Number.isFinite(n) || n < 0) {\n throw new BadRequest(`pipeline.${name}(): ${name} must be a non-negative finite number`);\n }\n }\n\n /* --------------------------- shape-keeping --------------------------- */\n\n match(filter: FilterInput<TDoc>): this {\n this.stages.push({ $match: filter });\n return this;\n }\n\n sort(sort: SortKeys<TDoc>): this {\n this.stages.push({ $sort: sort });\n return this;\n }\n\n limit(n: number): this {\n this.assertNonNegativeFinite('limit', n);\n this.stages.push({ $limit: n });\n return this;\n }\n\n skip(n: number): this {\n this.assertNonNegativeFinite('skip', n);\n this.stages.push({ $skip: n });\n return this;\n }\n\n sample(n: number): this {\n this.assertNonNegativeFinite('sample', n);\n this.stages.push({ $sample: { size: n } });\n return this;\n }\n\n /**\n * `$geoNear` — requires a `2dsphere`/`2d` index and MUST be the first stage.\n * Adds the computed distance to `spec.distanceField` on every output doc.\n */\n geoNear<const S extends GeoNearSpec>(\n spec: S,\n ): PipelineBuilder<TClients, TDb, GeoNearOutput<TDoc, S>> {\n if (this.stages.length > 0) {\n throw new Error('pipeline.geoNear(): $geoNear must be the first pipeline stage');\n }\n return this.derive<GeoNearOutput<TDoc, S>>({ $geoNear: spec });\n }\n\n /* --------------------------- shape-changing -------------------------- */\n\n project<const P extends Projection<TDoc>>(\n projection: P,\n ): PipelineBuilder<TClients, TDb, Projected<TDoc, P>> {\n return this.derive<Projected<TDoc, P>>({ $project: projection });\n }\n\n addFields<const P extends Projection<TDoc>>(\n fields: P,\n ): PipelineBuilder<TClients, TDb, Added<TDoc, P>> {\n return this.derive<Added<TDoc, P>>({ $addFields: fields });\n }\n\n set<const P extends Projection<TDoc>>(fields: P): PipelineBuilder<TClients, TDb, Added<TDoc, P>> {\n return this.derive<Added<TDoc, P>>({ $set: fields });\n }\n\n unset<const F extends string | readonly string[]>(\n fields: F,\n ): PipelineBuilder<TClients, TDb, Unsetted<TDoc, F>> {\n return this.derive<Unsetted<TDoc, F>>({ $unset: fields });\n }\n\n count<const F extends string>(field: F): PipelineBuilder<TClients, TDb, { [K in F]: number }> {\n return this.derive<{ [K in F]: number }>({ $count: field });\n }\n\n group<const G extends GroupSpec<TDoc>>(\n group: G,\n ): PipelineBuilder<TClients, TDb, Grouped<TDoc, G>> {\n return this.derive<Grouped<TDoc, G>>({ $group: group });\n }\n\n unwind<const P extends UnwindSpec>(path: P): PipelineBuilder<TClients, TDb, Unwound<TDoc, P>> {\n return this.derive<Unwound<TDoc, P>>({ $unwind: path });\n }\n\n lookup<\n const F extends ExtractCollectionNames<TClients, TDb>,\n const A extends string,\n const O extends Document = ForeignDocOf<TClients, TDb, F>,\n >(\n spec: LookupSpecFor<TClients, TDb, TDoc, F> & {\n as: A;\n pipeline?:\n | Document[]\n | ((\n sub: PipelineBuilder<TClients, TDb, ForeignDocOf<TClients, TDb, F>>,\n ) => PipelineBuilder<TClients, TDb, O> | Document[]);\n },\n ): PipelineBuilder<TClients, TDb, LookupJoinedFor<TClients, TDb, TDoc, F, A, O>> {\n return this.derive<LookupJoinedFor<TClients, TDb, TDoc, F, A, O>>({\n $lookup: this.evalLookup(spec),\n });\n }\n\n facet<const F extends FacetSpec<TClients, TDb, TDoc>>(\n facets: F,\n ): PipelineBuilder<TClients, TDb, FacetOutput<TClients, TDb, TDoc, F>> {\n return this.derive<FacetOutput<TClients, TDb, TDoc, F>>({ $facet: this.evalFacets(facets) });\n }\n\n /* ------------------------------ terminals ---------------------------- */\n\n /** Run the pipeline and return every output document. */\n toArray(): Promise<TDoc[]> {\n const run = (r: ResolvedQueryOptions) =>\n this.deps\n .coll()\n .aggregate<TDoc>(this.stages, this.deps.mergeDriver(r.driverOpts, r.sdk))\n .toArray();\n if (this.deps.cachedAggregate) {\n return this.deps.cachedAggregate<string, TDoc[]>({\n collection: this.deps.logical,\n opName: 'mongo.pipeline',\n pipeline: this.stages,\n ...(this.deps.options !== undefined ? { options: this.deps.options } : {}),\n execute: run,\n });\n }\n return defineCrudOp(\n this.deps.crudDeps,\n this.deps.logical,\n 'mongo.pipeline',\n run,\n this.deps.options,\n false,\n { pipeline: this.stages },\n );\n }\n\n /** Run the pipeline and return the first output document (or null). */\n async first(): Promise<TDoc | null> {\n const run = async (r: ResolvedQueryOptions) => {\n const cursor = this.deps\n .coll()\n .aggregate<TDoc>(this.stages, this.deps.mergeDriver(r.driverOpts, r.sdk));\n try {\n return await cursor.tryNext();\n } finally {\n await cursor.close();\n }\n };\n // Distinct op name so `first()` never shares a cache entry with\n // `toArray()` on the same pipeline (they would collide on the key).\n if (this.deps.cachedAggregate) {\n return this.deps.cachedAggregate<string, TDoc | null>({\n collection: this.deps.logical,\n opName: 'mongo.pipeline.first',\n pipeline: this.stages,\n ...(this.deps.options !== undefined ? { options: this.deps.options } : {}),\n execute: run,\n });\n }\n return defineCrudOp(\n this.deps.crudDeps,\n this.deps.logical,\n 'mongo.pipeline.first',\n run,\n this.deps.options,\n false,\n { pipeline: this.stages },\n );\n }\n\n /** Streaming cursor (raw driver cursor; no retry / trace). */\n cursor(): AggregationCursor<TDoc> {\n return this.deps.coll().aggregate<TDoc>(this.stages, this.deps.options as AggregateOptions);\n }\n\n /* ------------------------------ internals ---------------------------- */\n\n private derive<NewDoc extends Document>(stage: Document): PipelineBuilder<TClients, TDb, NewDoc> {\n return new PipelineBuilder<TClients, TDb, NewDoc>(this.deps, [...this.stages, stage]);\n }\n\n private evalLookup(spec: Record<string, unknown>): Document {\n const { pipeline, ...rest } = spec;\n if (typeof pipeline === 'function') {\n const sub = new PipelineBuilder<any, any, Document>(this.deps, []);\n const result = (pipeline as (s: PipelineBuilder<any, any, Document>) => unknown)(sub);\n return { ...rest, pipeline: normalizeSubPipeline(result, '$lookup') };\n }\n return spec as Document;\n }\n\n private evalFacets(facets: Record<string, unknown>): Record<string, Document[]> {\n const out: Record<string, Document[]> = {};\n for (const [name, branch] of Object.entries(facets)) {\n if (typeof branch === 'function') {\n const sub = new PipelineBuilder<any, any, any>(this.deps, []);\n const result = (branch as (s: PipelineBuilder<any, any, any>) => unknown)(sub);\n out[name] = normalizeSubPipeline(result, `$facet.${name}`);\n } else {\n out[name] = branch as Document[];\n }\n }\n return out;\n }\n}\n\n/**\n * Normalize a sub-pipeline callback result into a raw `Document[]`.\n *\n * Sub-pipelines may be written as a CHAINED builder (`(o) => o.match(...).project(...)`)\n * or a raw array of stages. A common footgun is the array form where each element is\n * itself a builder result — `[o.match(...), o.project(...)]` — which silently produces\n * garbage stages and fails in Mongo with \"must contain exactly one field\" (code 40323).\n * We detect and reject that eagerly with a descriptive error.\n */\nexport const normalizeSubPipeline = (result: unknown, where: string): Document[] => {\n if (Array.isArray(result) && result.some((s) => s instanceof PipelineBuilder)) {\n throw new TypeError(\n `aggregation sub-pipeline (${where}) must be written as a chained builder — e.g. ` +\n '`(o) => o.match(...).project(...)` — not as an array of builder results like ' +\n '`[o.match(...), o.project(...)]` (each element is a builder, not a stage).',\n );\n }\n return result instanceof PipelineBuilder ? result.raw() : (result as Document[]);\n};\n\n/**\n * Create a non-executable, stage-only builder. Used to evaluate `$lookup` /\n * `$facet` sub-pipelines in the callback `aggregate()` API — the sub-pipeline\n * is only ever read via `.raw()`, never executed.\n */\nexport const stageBuilder = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n TDoc extends Document,\n>(): PipelineBuilder<TClients, TDb, TDoc> =>\n new PipelineBuilder<TClients, TDb, TDoc>({\n logical: '',\n coll: () => {\n throw new Error('stage-only pipeline builders cannot be executed');\n },\n crudDeps: {\n trace: () => Promise.reject(new Error('stage-only pipeline builders cannot be executed')),\n meta: () => ({ collection: '', physicalCollection: '', db: '', op: '' }),\n },\n mergeDriver: () => ({}),\n });\n","import type { Document } from 'mongodb';\nimport type { FilterInput } from '../shared/filter-types.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../types.ts';\nimport { normalizeSubPipeline, type PipelineBuilder, stageBuilder } from './pipeline-builder.ts';\nimport type {\n ForeignDocOf,\n GeoNearSpec,\n GroupSpec,\n LookupSpecFor,\n Projection,\n SortKeys,\n UnwindSpec,\n} from './pipeline-types.ts';\n\n/**\n * Typed aggregation-stage builder for the `db.aggregate(collection, (stages) =>\n * [...])` callback API. Each stage is validated against the source document\n * (`match` fields autocomplete and typo'd fields are compile errors), `$lookup`\n * sub-pipelines are scoped to the related collection, and `$facet` branches get\n * their own typed sub-builder. For inferred result types use the chained\n * `db.pipeline()` builder instead (`src/service/pipeline-builder.ts`).\n */\nexport interface AggregationStages<\n TDoc extends Document = Document,\n TClients extends DbClientsDefinition = DbClientsDefinition,\n TDb extends ExtractDbNames<TClients> = ExtractDbNames<TClients>,\n> {\n match(filter: FilterInput<TDoc>): { $match: FilterInput<TDoc> };\n project(fields: Projection<TDoc>): { $project: Projection<TDoc> };\n addFields(fields: Projection<TDoc>): { $addFields: Projection<TDoc> };\n set(fields: Projection<TDoc>): { $set: Projection<TDoc> };\n unset(fields: string | string[]): { $unset: string | string[] };\n sort(sort: SortKeys<TDoc>): { $sort: SortKeys<TDoc> };\n limit(n: number): { $limit: number };\n skip(n: number): { $skip: number };\n count(field: string): { $count: string };\n group(group: GroupSpec<TDoc>): { $group: GroupSpec<TDoc> };\n /**\n * `$geoNear` — requires a `2dsphere`/`2d` index and MUST be the first stage\n * (throws otherwise).\n */\n geoNear(spec: GeoNearSpec): { $geoNear: GeoNearSpec };\n lookup<\n const F extends ExtractCollectionNames<TClients, TDb>,\n const A extends string,\n const O extends Document = ForeignDocOf<TClients, TDb, F>,\n >(\n params: LookupSpecFor<TClients, TDb, TDoc, F> & {\n as: A;\n pipeline?:\n | Document[]\n | ((\n sub: PipelineBuilder<TClients, TDb, ForeignDocOf<TClients, TDb, F>>,\n ) => PipelineBuilder<TClients, TDb, O> | Document[]);\n },\n ): { $lookup: Document };\n facet(\n facets: Record<\n string,\n Document[] | ((stages: AggregationStages<TDoc, TClients, TDb>) => Document[])\n >,\n ): { $facet: Record<string, Document[]> };\n unwind(path: UnwindSpec): { $unwind: UnwindSpec };\n fill(params: Document): { $fill: Document };\n bucket(params: Document): { $bucket: Document };\n bucketAuto(params: Document): { $bucketAuto: Document };\n densify(params: Document): { $densify: Document };\n}\n\nexport const buildAggregationStages = <\n TDoc extends Document = Document,\n TClients extends DbClientsDefinition = DbClientsDefinition,\n TDb extends ExtractDbNames<TClients> = ExtractDbNames<TClients>,\n>(): AggregationStages<TDoc, TClients, TDb> => {\n // Tracks emitted stages so `$geoNear` (first-stage-only) can be guarded.\n let emitted = 0;\n const mark = <T>(stage: T): T => {\n emitted++;\n return stage;\n };\n return {\n match: (filter) => mark({ $match: filter }),\n project: (fields) => mark({ $project: fields }),\n addFields: (fields) => mark({ $addFields: fields }),\n set: (fields) => mark({ $set: fields }),\n unset: (fields) => mark({ $unset: fields }),\n sort: (sort) => mark({ $sort: sort }),\n limit: (n) => mark({ $limit: n }),\n skip: (n) => mark({ $skip: n }),\n count: (field) => mark({ $count: field }),\n group: (group) => mark({ $group: group }),\n lookup: <\n const F extends ExtractCollectionNames<TClients, TDb>,\n const A extends string,\n const O extends Document = ForeignDocOf<TClients, TDb, F>,\n >(\n params: LookupSpecFor<TClients, TDb, TDoc, F> & {\n as: A;\n pipeline?:\n | Document[]\n | ((\n sub: PipelineBuilder<TClients, TDb, ForeignDocOf<TClients, TDb, F>>,\n ) => PipelineBuilder<TClients, TDb, O> | Document[]);\n },\n ): { $lookup: Document } => {\n const { pipeline, ...rest } = params;\n if (typeof pipeline === 'function') {\n const sub = stageBuilder<TClients, TDb, ForeignDocOf<TClients, TDb, F>>();\n const result = (pipeline as (s: PipelineBuilder<TClients, TDb, any>) => unknown)(sub);\n return mark({\n $lookup: {\n ...rest,\n pipeline: normalizeSubPipeline(result, '$lookup'),\n },\n });\n }\n return mark({ $lookup: params });\n },\n facet: (facets) => {\n const out: Record<string, Document[]> = {};\n for (const [name, branch] of Object.entries(facets)) {\n out[name] =\n typeof branch === 'function'\n ? (branch as (stages: AggregationStages<TDoc, TClients, TDb>) => Document[])(\n buildAggregationStages<TDoc, TClients, TDb>(),\n )\n : branch;\n }\n return mark({ $facet: out });\n },\n unwind: (path) => mark({ $unwind: path }),\n fill: (params) => mark({ $fill: params }),\n bucket: (params) => mark({ $bucket: params }),\n bucketAuto: (params) => mark({ $bucketAuto: params }),\n densify: (params) => mark({ $densify: params }),\n geoNear: (spec) => {\n if (emitted > 0) {\n throw new Error('aggregate.geoNear(): $geoNear must be the first pipeline stage');\n }\n return mark({ $geoNear: spec });\n },\n };\n};\n","/**\n * Low-level + typed-pipeline aggregation ops: `aggregate` (callback stage API,\n * returns a live cursor) and `pipeline` (the fully type-safe chained\n * `PipelineBuilder`). Both funnel through the shared op pipeline.\n */\nimport type { AggregateOptions, AggregationCursor, Document } from 'mongodb';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport { type AggregationStages, buildAggregationStages } from '../aggregation-stages.ts';\nimport type { CrudOpDeps } from '../crud-op.ts';\nimport { defineCrudOp } from '../crud-op.ts';\nimport { PipelineBuilder } from '../pipeline-builder.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type { AggregationCtx, AggregationDocOf } from './types.ts';\n\n/** Build `aggregate` + `pipeline` from the shared aggregation context. */\nexport const makeAggregateOps = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: AggregationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = AggregationDocOf<TClients, TDb, X>;\n\n const { deps, coll, mergeAggOptions, cachedAggregate } = ctx;\n\n /** Low-level aggregate: returns a live cursor wrapped in the op pipeline. */\n const aggregate = async <X extends C, TResult extends Document = Document>(\n collection: X,\n pipelineBuilder: (stages: AggregationStages<DocOf2<X>, TClients, TDb>) => Document[],\n options?: AggregateOptions & QueryOptions,\n ): Promise<AggregationCursor<TResult>> => {\n const stages = buildAggregationStages<DocOf2<X>, TClients, TDb>();\n const pipeline = pipelineBuilder(stages);\n return defineCrudOp(\n deps,\n collection,\n 'mongo.aggregate',\n (r) => coll(collection).aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk)),\n options,\n false,\n { pipeline },\n );\n };\n\n /**\n * Fully type-safe, chainable pipeline builder. Each stage is typed against\n * the current document shape, `$lookup` sub-pipelines are scoped to the\n * related collection, and `$facet` branches get typed sub-builders — the\n * result type of `.toArray()` / `.first()` is inferred through the chain.\n */\n const pipeline = <const X extends C>(\n collection: X,\n options?: AggregateOptions & QueryOptions,\n ): PipelineBuilder<TClients, TDb, DocOf2<X>> =>\n new PipelineBuilder<TClients, TDb, DocOf2<X>>({\n logical: collection,\n coll: () => coll(collection),\n crudDeps: deps as unknown as CrudOpDeps<string>,\n mergeDriver: mergeAggOptions,\n ...(options !== undefined ? { options } : {}),\n cachedAggregate,\n });\n\n return { aggregate, pipeline };\n};\n","/**\n * Aggregation helpers shared by every op: `mergeAggOptions` (merge driver +\n * SDK options into a full `AggregateOptions`, forwarding `batchSize`), the\n * `DATE_PART_FORMATS` lookup for date-bucket `$dateToString` formats, and the\n * cache plumbing — `collectAggSources` (which source collections a pipeline\n * reads, for invalidation) and `isCacheablePipeline` (skip caching for\n * write/non-deterministic stages).\n */\nimport type { AggregateOptions, Document } from 'mongodb';\nimport type { AggregationSdkOptions, DateRangeConfig } from './types.ts';\n\n/** Merge resolved SDK options into the driver's aggregate options. */\nexport const mergeAggOptions = (\n driverOpts: Record<string, unknown>,\n sdk: AggregationSdkOptions,\n): AggregateOptions => ({\n ...(driverOpts as AggregateOptions),\n ...(sdk.session !== undefined ? { session: sdk.session } : {}),\n ...(sdk.maxTimeMS !== undefined ? { maxTimeMS: sdk.maxTimeMS } : {}),\n ...(sdk.hint !== undefined ? { hint: sdk.hint } : {}),\n ...(sdk.batchSize !== undefined ? { batchSize: sdk.batchSize } : {}),\n});\n\n/** `$dateToString` format per granularity for `dateRangeAnalysis`. */\nexport const DATE_PART_FORMATS: Record<NonNullable<DateRangeConfig['granularity']>, string> = {\n hour: '%Y-%m-%dT%H',\n day: '%Y-%m-%d',\n week: '%Y-W%V',\n month: '%Y-%m',\n year: '%Y',\n};\n\n/**\n * Collect every SOURCE collection an aggregation pipeline reads from, so cached\n * results can be invalidated when ANY of them changes. Starts with the primary\n * collection + any additional logical sources the op knows about (e.g.\n * `lookupJoin`'s `fromCollection`s), then walks the pipeline for:\n *\n * - `$lookup.from` (recursing into `$lookup.pipeline`)\n * - `$unionWith.coll` (recursing into `$unionWith.pipeline`)\n * - `$facet` branches (recursing into each branch's stages)\n *\n * The returned names are resolved to physical collection keys by the caller\n * (`resolve(logical)` — a known logical name — else treated as an already\n * physical name, which is what `lookupJoin` emits).\n */\nexport const collectAggSources = (\n primaryLogical: string,\n pipeline: Document[],\n extraLogical: string[] = [],\n): string[] => {\n const sources = new Set<string>([primaryLogical, ...extraLogical]);\n const visit = (stages: unknown): void => {\n if (!Array.isArray(stages)) return;\n for (const stage of stages) {\n if (!stage || typeof stage !== 'object') continue;\n const s = stage as Record<string, unknown>;\n const lookup = s.$lookup as Record<string, unknown> | undefined;\n if (lookup && typeof lookup === 'object') {\n if (typeof lookup.from === 'string') sources.add(lookup.from);\n if (Array.isArray(lookup.pipeline)) visit(lookup.pipeline);\n }\n const union = s.$unionWith as Record<string, unknown> | undefined;\n if (union && typeof union === 'object') {\n if (typeof union.coll === 'string') sources.add(union.coll);\n if (Array.isArray(union.pipeline)) visit(union.pipeline);\n }\n const facet = s.$facet as Record<string, unknown> | undefined;\n if (facet && typeof facet === 'object') {\n for (const branch of Object.values(facet)) visit(branch); // each branch is a stage list\n }\n }\n };\n visit(pipeline);\n return [...sources];\n};\n\n/**\n * Whether an aggregation pipeline is safe to cache. Results are NOT cached when\n * the pipeline writes (`$out` / `$merge`) or is non-deterministic (`$sample`).\n * Non-deterministic expressions beyond `$sample` (`$rand`, `$function`) are not\n * auto-detected — callers should opt out per op with `{ cache: false }`. The\n * check recurses into `$lookup.pipeline` and `$facet` branches.\n */\nexport const isCacheablePipeline = (pipeline: Document[]): boolean => {\n for (const stage of pipeline) {\n if (!stage || typeof stage !== 'object') continue;\n if ('$out' in stage || '$merge' in stage || '$sample' in stage) return false;\n const s = stage as Record<string, unknown>;\n const lookup = s.$lookup as { pipeline?: Document[] } | undefined;\n if (lookup && Array.isArray(lookup.pipeline) && !isCacheablePipeline(lookup.pipeline)) {\n return false;\n }\n const facet = s.$facet as Record<string, unknown> | undefined;\n if (facet && typeof facet === 'object') {\n for (const branch of Object.values(facet)) {\n if (Array.isArray(branch) && !isCacheablePipeline(branch)) return false;\n }\n }\n }\n return true;\n};\n","/**\n * Cached-aggregation read pipeline — the aggregation analog of the CRUD read\n * path (`crud/context.ts` `read()`): write-through `QueryCache` + in-flight\n * dedup for MATERIALIZED aggregation results.\n *\n * Aggregation results are derived documents, so schema-drift checking is NOT\n * applied here (drift is for raw reads). Caching is skipped when:\n * - the service has no cache (`perf:false` / `cache:null`) or the per-op\n * `cache:false` bypass is set;\n * - a session is present (transactional reads must hit the DB);\n * - the pipeline is not cacheable — `$out`/`$merge` writes or `$sample`\n * non-determinism (see `isCacheablePipeline`).\n *\n * Keys are db-namespaced by the PRIMARY collection; entries are additionally\n * registered under EVERY source collection (see `collectAggSources`) so a write\n * to ANY source invalidates them — this is what keeps `$lookup`/`$unionWith`\n * joins correct under write-through invalidation and `cacheWatch`.\n *\n * `aggregate()` (live cursor) and `pipeline().cursor()` are NOT cached — they\n * stream; use `pipeline().toArray()` / `.first()` for cached materialization.\n */\nimport type { AggregateOptions, Db, Document } from 'mongodb';\nimport type { InFlight } from '../../cache/in-flight.ts';\nimport { cacheCollectionKey, type QueryCache } from '../../cache/query-cache.ts';\nimport { stableHash } from '../../utils/hash.ts';\nimport { defineCrudOp } from '../crud-op.ts';\nimport type { OpDeps } from '../op-deps.ts';\nimport {\n type QueryOptions,\n type ResolvedQueryOptions,\n resolveQueryOptions,\n} from '../query-options.ts';\nimport { collectAggSources, isCacheablePipeline } from './helpers.ts';\n\n/**\n * The context the cached runner needs. Both the aggregation ops and the\n * `$facet` pagination strategy satisfy it structurally (their `opts` expose the\n * shared `cache` / `dedupeReads` / `inFlight` knobs).\n */\nexport type CachedAggregateCtx<C extends string> = {\n client: Db;\n deps: OpDeps<C>;\n opts: { cache?: QueryCache; dedupeReads: boolean; inFlight?: InFlight };\n resolve: (logical: string) => string;\n};\n\n/** Build the cached-aggregation runner from a collection-set-generic context. */\nexport const createCachedAggregate = <C extends string>(ctx: CachedAggregateCtx<C>) => {\n const { client, deps, opts, resolve } = ctx;\n const cache = opts.cache;\n\n return async <X extends string, T>(input: {\n collection: X;\n opName: string;\n pipeline: Document[];\n options?: AggregateOptions & QueryOptions;\n /** Additional LOGICAL source collections (e.g. `lookupJoin` fromCollections). */\n sources?: string[];\n execute: (resolved: ResolvedQueryOptions) => Promise<T>;\n }): Promise<T> => {\n const { collection: collectionName, opName, pipeline, options, sources = [], execute } = input;\n // `collectionName` is a known logical collection at the call site; the\n // widened `X extends string` keeps this assignable to `CachedAggregate`.\n const collection = collectionName as unknown as C;\n const physical = resolve(String(collection));\n const resolved = resolveQueryOptions(options);\n const noSession = !resolved.sdk.session;\n const useCache =\n cache !== undefined && noSession && resolved.cache !== false && isCacheablePipeline(pipeline);\n const shouldDedupe =\n resolved.dedupe !== false &&\n (resolved.dedupe === true || (opts.dedupeReads === true && noSession)) &&\n opts.inFlight !== undefined;\n\n // Keep the trace + transient-retry wrapper identical to today's path, but\n // record the pipeline as what-was-sent so the debugbar shows the full\n // aggregation (this covers `paginateFlexible`'s `$facet` too).\n const runDriver = (): Promise<T> =>\n defineCrudOp(deps, collection, opName, execute, options, false, { pipeline });\n\n // Only hash when caching (noSession is guaranteed) — a live session would\n // not serialize cleanly.\n const key = useCache\n ? cache!.key(\n cacheCollectionKey(client.databaseName, physical),\n stableHash([opName, pipeline, options]),\n )\n : undefined;\n\n // Resolve every source collection → db-namespaced physical key, lazily (only\n // on a cache miss, so disabled caches pay nothing). Known logical names\n // resolve via `resolve()`; already-physical names (raw stages, `lookupJoin`)\n // pass through (a `resolve()` call on them would throw \"Unknown collection\").\n const toSourceKeys = () =>\n collectAggSources(String(collection), pipeline, sources).map((name) => {\n try {\n return cacheCollectionKey(client.databaseName, resolve(name));\n } catch {\n return cacheCollectionKey(client.databaseName, name);\n }\n });\n\n const runOnce = (): Promise<T> => {\n if (useCache && key) {\n // Capture the version of EVERY source collection before fetching so a\n // write to any of them mid-flight can never be hidden by a late set.\n const sourceKeys = toSourceKeys();\n const primaryKey = cacheCollectionKey(client.databaseName, physical);\n const versions: Record<string, number> = { [primaryKey]: cache!.versionOf(primaryKey) };\n for (const col of sourceKeys) {\n if (!(col in versions)) versions[col] = cache!.versionOf(col);\n }\n const hit = cache!.get(key) as T | undefined;\n if (hit !== undefined) return Promise.resolve(hit);\n return runDriver().then((value) => {\n cache!.set(key, value, undefined, sourceKeys, versions);\n return value;\n });\n }\n return runDriver();\n };\n\n if (shouldDedupe) {\n // Version-scoped like the CRUD read path: a post-invalidation reader must\n // not join a pre-invalidation in-flight aggregation.\n const primaryKey = cacheCollectionKey(client.databaseName, physical);\n const gen = cache !== undefined ? cache.versionOf(primaryKey) : '';\n const dedupeKey = `${primaryKey}|${gen}|${opName}|${stableHash([pipeline, options])}`;\n return await opts.inFlight!.run(dedupeKey, runOnce);\n }\n return await runOnce();\n };\n};\n","/**\n * Grouping aggregation ops: `groupBy` (bucket by key with accumulators) and\n * `dateRangeAnalysis` (bucket a date field by hour/day/week/month/year). Both\n * build a `$group` pipeline and run it through the shared op pipeline.\n */\nimport type { AggregateOptions, Document } from 'mongodb';\nimport { BadRequest } from '../../errors/index.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport { DATE_PART_FORMATS } from './helpers.ts';\nimport type {\n AggregationCtx,\n AggregationDocOf,\n DateRangeConfig,\n GroupByConfig,\n PipelineCustomization,\n} from './types.ts';\n\n/** Build `groupBy` + `dateRangeAnalysis` from the shared aggregation context. */\nexport const makeGroupOps = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: AggregationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = AggregationDocOf<TClients, TDb, X>;\n\n const { coll, mergeAggOptions, cachedAggregate } = ctx;\n\n /** Group documents by a key with optional accumulators/sort/limit (e.g. revenue per status). */\n const groupBy = async <X extends C, TResult extends Document = Document>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n config: GroupByConfig,\n customization: PipelineCustomization = {},\n options?: AggregateOptions & QueryOptions,\n ): Promise<TResult[]> => {\n if (config.limit !== undefined && (!Number.isFinite(config.limit) || config.limit < 0)) {\n throw new BadRequest('groupBy: `limit` must be a non-negative finite number');\n }\n const pipeline: Document[] = [\n ...(customization.prePipeline ?? []),\n { $match: baseFilter },\n { $group: { _id: config.groupBy, ...(config.accumulate ?? {}) } },\n ...(config.sort && Object.keys(config.sort).length > 0 ? [{ $sort: config.sort }] : []),\n ...(config.limit !== undefined ? [{ $limit: config.limit }] : []),\n ...(customization.postPipeline ?? []),\n ];\n return cachedAggregate<X, TResult[]>({\n collection,\n opName: 'mongo.groupBy',\n pipeline,\n ...(options !== undefined ? { options } : {}),\n execute: (r) =>\n coll(collection)\n .aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray(),\n });\n };\n\n /** Aggregate a metric over date buckets (hour/day/week/month/year) within a range. */\n const dateRangeAnalysis = async <X extends C, TResult extends Document = Document>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n dateConfig: DateRangeConfig,\n analysisConfig: {\n accumulate?: Record<string, unknown>;\n sort?: Record<string, 1 | -1>;\n limit?: number;\n } = {},\n customization: PipelineCustomization = {},\n options?: AggregateOptions & QueryOptions,\n ): Promise<TResult[]> => {\n if (\n analysisConfig.limit !== undefined &&\n (!Number.isFinite(analysisConfig.limit) || analysisConfig.limit < 0)\n ) {\n throw new BadRequest('dateRangeAnalysis: `limit` must be a non-negative finite number');\n }\n const granularity = dateConfig.granularity ?? 'day';\n const format = DATE_PART_FORMATS[granularity];\n const datePart = {\n $dateToString: { format, date: `$${dateConfig.dateField}` },\n };\n const pipeline: Document[] = [\n ...(customization.prePipeline ?? []),\n {\n $match: {\n ...baseFilter,\n [dateConfig.dateField]: { $gte: dateConfig.startDate, $lte: dateConfig.endDate },\n },\n },\n { $group: { _id: datePart, ...(analysisConfig.accumulate ?? {}) } },\n ...(analysisConfig.sort && Object.keys(analysisConfig.sort).length > 0\n ? [{ $sort: analysisConfig.sort }]\n : []),\n ...(analysisConfig.limit !== undefined ? [{ $limit: analysisConfig.limit }] : []),\n ...(customization.postPipeline ?? []),\n ];\n return cachedAggregate<X, TResult[]>({\n collection,\n opName: 'mongo.dateRangeAnalysis',\n pipeline,\n ...(options !== undefined ? { options } : {}),\n execute: (r) =>\n coll(collection)\n .aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray(),\n });\n };\n\n return { groupBy, dateRangeAnalysis };\n};\n","/**\n * Join aggregation op — `lookupJoin`: `$lookup` one or more related\n * (logical) collections, optionally `$unwind`-ing the joined arrays (preserving\n * nulls). Single-collection hops built declaratively from `LookupConfig[]`.\n */\nimport type { AggregateOptions, Document } from 'mongodb';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type {\n AggregationCtx,\n AggregationDocOf,\n LookupConfig,\n PipelineCustomization,\n} from './types.ts';\n\n/** Build `lookupJoin` from the shared aggregation context. */\nexport const makeLookupJoinOp = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: AggregationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = AggregationDocOf<TClients, TDb, X>;\n\n const { coll, mergeAggOptions, resolve, cachedAggregate } = ctx;\n\n /** Join related docs via `$lookup` + optional `$unwind` (single collection hop). */\n const lookupJoin = async <X extends C, TResult extends Document = DocOf2<X>>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n lookups: LookupConfig[],\n customization: PipelineCustomization = {},\n options?: AggregateOptions & QueryOptions,\n ): Promise<TResult[]> => {\n const pipeline: Document[] = [\n ...(customization.prePipeline ?? []),\n { $match: baseFilter },\n ...lookups.map((lookup) => ({\n $lookup: {\n from: resolve(lookup.fromCollection),\n localField: lookup.localField,\n foreignField: lookup.foreignField,\n as: lookup.as,\n ...(lookup.pipeline ? { pipeline: lookup.pipeline } : {}),\n },\n })),\n ...lookups\n .filter((lookup) => lookup.unwindSingle)\n .map((lookup) => ({\n $unwind: { path: `$${lookup.as}`, preserveNullAndEmptyArrays: true },\n })),\n ...(customization.postPipeline ?? []),\n ];\n return cachedAggregate<X, TResult[]>({\n collection,\n opName: 'mongo.lookupJoin',\n pipeline,\n ...(options !== undefined ? { options } : {}),\n // Writes to any joined collection must invalidate the cached join.\n sources: lookups.map((l) => l.fromCollection),\n execute: (r) =>\n coll(collection)\n .aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray(),\n });\n };\n\n return { lookupJoin };\n};\n","import { BadRequest } from '../errors/index.ts';\n\nexport interface CrudListQuery {\n page?: number;\n limit?: number;\n}\n\nexport interface NormalizedPagination {\n page: number;\n limit: number;\n offset: number;\n}\n\n/**\n * Normalize + validate page/limit. Pure — no DB knowledge.\n * - `page` is floored to >= 1\n * - `limit` must be within [1, maxLimit] or a `BadRequest` is thrown\n */\nexport const normalizePageLimit = (\n query: CrudListQuery,\n maxLimit: number,\n defaults: { page?: number; limit?: number } = {},\n): NormalizedPagination => {\n const rawPage = query.page ?? defaults.page ?? 1;\n const limit = query.limit ?? defaults.limit ?? 10;\n\n // Reject NaN / Infinity / non-numbers up front — `Math.floor(NaN)` would\n // otherwise flow into `$skip: NaN` as an obscure driver error.\n if (typeof rawPage !== 'number' || !Number.isFinite(rawPage)) {\n throw new BadRequest('page must be a finite number');\n }\n if (typeof limit !== 'number' || !Number.isFinite(limit)) {\n throw new BadRequest('limit must be a finite number');\n }\n if (limit < 1) throw new BadRequest('limit must be >= 1');\n if (limit > maxLimit) throw new BadRequest(`limit ${limit} exceeds maxLimit ${maxLimit}`);\n\n const page = Math.max(1, Math.floor(rawPage));\n return { page, limit, offset: (page - 1) * limit };\n};\n","export interface AggregationMeta {\n executionTimeMs?: number;\n indexesUsed?: string[];\n}\n\n/** Uniform pagination result shape (shared by all list/paginate/search ops). */\nexport interface PaginationResult<T> {\n data: T[];\n totalCount: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n currentPage: number;\n totalPages: number;\n aggregationMeta?: AggregationMeta;\n}\n\nexport const buildPaginationResult = <T>(\n data: T[],\n totalCount: number,\n page: number,\n limit: number,\n): PaginationResult<T> => {\n const totalPages = totalCount === 0 ? 0 : Math.ceil(totalCount / limit);\n return {\n data,\n totalCount,\n hasNextPage: page < totalPages,\n hasPrevPage: page > 1,\n currentPage: page,\n totalPages,\n };\n};\n","import type { Document, Filter } from 'mongodb';\n\nexport interface SearchConfig {\n /** Fields to search across. */\n searchFields: string[];\n /** Search term. */\n searchTerm: string;\n /** Loose per-character matching (`$regex` mode only). */\n fuzzy?: boolean;\n /** Case sensitivity (`$text` mode; `$regex` mode uses this too). */\n caseSensitive?: boolean;\n /** true → `$regex` search; false (default) → `$text` search. */\n useRegex?: boolean;\n /** `$text` search language (defaults to the server's default). */\n language?: string;\n /** `$text` diacritic sensitivity (default false → insensitive). */\n diacriticSensitive?: boolean;\n /**\n * When true, `textSearch` sorts by `searchScore` (textScore meta) instead of\n * the caller's sort. `$text`-mode only.\n */\n sortByScore?: boolean;\n}\n\nconst escapeRegex = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/** Build `$regex` search stages with an optional fuzzy (loose) pattern. */\nexport const buildRegexSearchStages = <T extends Document>(\n baseFilter: Filter<T>,\n searchConfig: SearchConfig,\n): Document[] => {\n const { searchFields, searchTerm, fuzzy = false, caseSensitive = false } = searchConfig;\n const escaped = escapeRegex(searchTerm);\n const pattern = fuzzy ? escaped.split('').join('.*') : escaped;\n const $or = searchFields.map((field) => ({\n [field]: { $regex: pattern, $options: caseSensitive ? '' : 'i' },\n }));\n return [{ $match: { ...baseFilter, $or } as Filter<T> }];\n};\n\n/** Build `$text` search stages with a `searchScore` meta field. */\nexport const buildTextSearchStages = <T extends Document>(\n baseFilter: Filter<T>,\n searchConfig: SearchConfig,\n): Document[] => [\n {\n $match: {\n ...baseFilter,\n $text: {\n $search: searchConfig.searchTerm,\n ...(searchConfig.caseSensitive !== undefined && {\n $caseSensitive: searchConfig.caseSensitive,\n }),\n ...(searchConfig.language !== undefined && { $language: searchConfig.language }),\n ...(searchConfig.diacriticSensitive !== undefined && {\n $diacriticSensitive: searchConfig.diacriticSensitive,\n }),\n },\n } as Filter<T>,\n },\n { $addFields: { searchScore: { $meta: 'textScore' } } },\n];\n\n/** Pick the search strategy based on `useRegex`. */\nexport const buildSearchStages = <T extends Document>(\n baseFilter: Filter<T>,\n searchConfig: SearchConfig,\n): Document[] =>\n searchConfig.useRegex\n ? buildRegexSearchStages(baseFilter, searchConfig)\n : buildTextSearchStages(baseFilter, searchConfig);\n","/**\n * Text-search aggregation op — `textSearch`: `$regex` (fuzzy, per-field `$or`)\n * or `$text` (`$search`, `$caseSensitive`, `$language`, `$diacriticSensitive`),\n * with `$facet` pagination and optional score sorting. Uses the search-stage\n * builders from `./aggregation-pipeline.ts`.\n */\nimport type { AggregateOptions, Document, Filter } from 'mongodb';\nimport { DEFAULT_MAX_LIMIT } from '../../shared/constants.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport { normalizePageLimit } from '../../shared/pagination-math.ts';\nimport { buildPaginationResult, type PaginationResult } from '../../shared/pagination-result.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport { buildSearchStages, type SearchConfig } from '../aggregation-pipeline.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type {\n AggregationCtx,\n AggregationDocOf,\n PipelineCustomization,\n TextSearchPagination,\n} from './types.ts';\n\n/** Build `textSearch` from the shared aggregation context. */\nexport const makeTextSearchOp = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: AggregationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = AggregationDocOf<TClients, TDb, X>;\n\n const { coll, mergeAggOptions, cachedAggregate } = ctx;\n\n /** Full-text / regex search with `$facet` pagination and optional score-sorting. */\n const textSearch = async <X extends C>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n searchConfig: SearchConfig,\n paginationConfig: TextSearchPagination = {},\n customization: PipelineCustomization = {},\n options?: AggregateOptions & QueryOptions,\n ): Promise<PaginationResult<DocOf2<X> & { searchScore?: number }>> => {\n const normalized = normalizePageLimit(\n {\n ...(paginationConfig.page !== undefined ? { page: paginationConfig.page } : {}),\n ...(paginationConfig.limit !== undefined ? { limit: paginationConfig.limit } : {}),\n },\n paginationConfig.maxLimit ?? DEFAULT_MAX_LIMIT,\n );\n const searchStages = buildSearchStages(\n baseFilter as unknown as Filter<DocOf2<X>>,\n searchConfig,\n );\n const pipeline: Document[] = [\n ...(customization.prePipeline ?? []),\n ...searchStages,\n {\n $facet: {\n data: [\n ...(searchConfig.sortByScore\n ? [{ $sort: { searchScore: { $meta: 'textScore' } } }]\n : []),\n ...(paginationConfig.sort && Object.keys(paginationConfig.sort).length > 0\n ? [{ $sort: paginationConfig.sort }]\n : []),\n { $skip: normalized.offset },\n { $limit: normalized.limit },\n ...(customization.postPipeline ?? []),\n ],\n totalCount: [{ $count: 'count' }],\n },\n },\n ];\n return cachedAggregate<X, PaginationResult<DocOf2<X> & { searchScore?: number }>>({\n collection,\n opName: 'mongo.textSearch',\n pipeline,\n ...(options !== undefined ? { options } : {}),\n execute: async (r) => {\n const rows = await coll(collection)\n .aggregate(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray();\n const row = rows[0] as\n | {\n data?: Array<DocOf2<X> & { searchScore?: number }>;\n totalCount?: Array<{ count: number }>;\n }\n | undefined;\n const data = row?.data ?? [];\n const totalCount = row?.totalCount?.[0]?.count ?? 0;\n return buildPaginationResult(data, totalCount, normalized.page, normalized.limit);\n },\n });\n };\n\n return { textSearch };\n};\n","/**\n * Aggregation op factory — `makeAggregationOps`. Composes the aggregation op\n * groups into one set per database:\n *\n * - `./aggregate.ts` — `aggregate` (callback stage API) + `pipeline` (typed builder)\n * - `./group.ts` — `groupBy` + `dateRangeAnalysis`\n * - `./text-search.ts` — `textSearch`\n * - `./lookup-join.ts` — `lookupJoin`\n *\n * All share a context (`./types.ts`) and the merged-options/date-format\n * helpers (`./helpers.ts`) built here.\n */\nimport type { Db, Document } from 'mongodb';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { makeOpDeps } from '../op-deps.ts';\nimport { makeAggregateOps } from './aggregate.ts';\nimport { createCachedAggregate } from './cached-read.ts';\nimport { makeGroupOps } from './group.ts';\nimport { mergeAggOptions } from './helpers.ts';\nimport { makeLookupJoinOp } from './lookup-join.ts';\nimport { makeTextSearchOp } from './text-search.ts';\nimport type { AggregationCtx, AggregationOpsOptions } from './types.ts';\n\n/**\n * Aggregation ops for one database: `aggregate`, `pipeline`, `groupBy`,\n * `textSearch`, `dateRangeAnalysis`, `lookupJoin`. All collection-name first\n * and schema-typed. Materializing ops (`pipeline().toArray()/.first()`,\n * `groupBy`, `dateRangeAnalysis`, `textSearch`, `lookupJoin`) route through the\n * shared cached-aggregation runner (`cachedAggregate`) — write-through cache +\n * in-flight dedup, invalidated per source collection. `aggregate()` and\n * `pipeline().cursor()` stream live cursors and stay uncached.\n */\nexport const makeAggregationOps = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n client: Db,\n dbLabel: string,\n logger: LoggerLike,\n opts: AggregationOpsOptions,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n\n const resolve = opts.resolveCollectionName;\n const deps = makeOpDeps<C>(logger, dbLabel, resolve, opts.wrapMongoErrors === true);\n const coll = (collection: C) => client.collection<Document>(resolve(String(collection)));\n\n const ctx: AggregationCtx<TClients, TDb> = {\n client,\n dbLabel,\n logger,\n opts,\n resolve,\n deps,\n coll,\n mergeAggOptions,\n cachedAggregate: createCachedAggregate<C>({ client, deps, opts, resolve }),\n };\n\n return {\n ...makeAggregateOps<TClients, TDb>(ctx),\n ...makeGroupOps<TClients, TDb>(ctx),\n ...makeTextSearchOp<TClients, TDb>(ctx),\n ...makeLookupJoinOp<TClients, TDb>(ctx),\n };\n};\n\n// Re-export the public aggregation types so the folder barrel matches the old\n// single-module exports.\nexport type {\n AggregationOpsOptions,\n DateRangeConfig,\n GroupByConfig,\n LookupConfig,\n PipelineCustomization,\n} from './types.ts';\n","/**\n * Schema-default materialization for writes.\n *\n * The schema DSL lets fields carry a `.default(v)` (`flags.hasDefault` +\n * `flags.defaultValue`). Until this module existed those defaults were only\n * *declared* — validation allowed the field to be absent, but nothing ever\n * wrote the value, so stored documents silently lacked defaulted fields. The\n * ORM's own timestamp stamping had the same shape (absent → stamped at\n * insert), and defaults should behave the same: materialized at write time so\n * every stored document carries them.\n *\n * `applySchemaDefaults` fills missing keys (in place, recursively into nested\n * object fields) with a per-document deep clone of the declared default, so\n * no two documents ever share a mutable default reference.\n */\n\nimport type { Document } from 'mongodb';\nimport type { ObjectField } from './types.ts';\n\n/** Deep-clone a default value; falls back to a shallow copy when\n * `structuredClone` is unavailable (very old runtimes). */\nconst cloneDefault = (value: unknown): unknown => {\n if (value === null || typeof value !== 'object') return value;\n if (typeof structuredClone === 'function') return structuredClone(value);\n return Array.isArray(value) ? [...value] : { ...(value as Record<string, unknown>) };\n};\n\n/**\n * Fill schema defaults into `doc` (in place). Only *absent* keys are written;\n * explicitly-provided values (including `undefined`, which the write pipeline\n * strips afterwards) are never overwritten. Nested object fields are recursed\n * into so their inner defaults materialize too.\n *\n * @param schema - The collection's declared schema (`ObjectField`), if any.\n * @param doc - Document being created or fully replaced.\n */\nexport const applySchemaDefaults = (schema: ObjectField | undefined, doc: Document): void => {\n if (!schema || doc === null || typeof doc !== 'object' || Array.isArray(doc)) return;\n\n for (const [key, prop] of Object.entries(schema.properties)) {\n if (key in doc && doc[key] !== undefined) {\n // Present value: recurse so nested defaults materialize around it.\n if (\n prop.kind === 'object' &&\n doc[key] !== null &&\n typeof doc[key] === 'object' &&\n !Array.isArray(doc[key])\n ) {\n applySchemaDefaults(prop, doc[key] as Document);\n }\n continue;\n }\n if (prop.flags.hasDefault) {\n doc[key] = cloneDefault(prop.flags.defaultValue);\n }\n }\n};\n","/**\n * `undefined`-value handling for write payloads.\n *\n * TypeScript signals \"absent\" with `undefined`, and object spreads commonly\n * leave optional fields as `undefined` (`{ ...(x ? { a: x } : {}) }` patterns).\n * The MongoDB driver serializes explicit `undefined` as `null`, which then\n * violates a strict `$jsonSchema` validator (string/date/objectId fields\n * reject `null`). Stripping `undefined` keys — never `null` — makes \"absent\"\n * behave as absent on the wire.\n */\n\n/** Strip `undefined` values from a document's own (top-level) keys, in place. */\nexport const stripUndefinedKeys = <T extends Record<string, unknown>>(doc: T): T => {\n for (const key of Object.keys(doc)) {\n if (doc[key] === undefined) {\n delete (doc as Record<string, unknown>)[key];\n }\n }\n return doc;\n};\n\n/**\n * Strip `undefined` values from an update payload: top-level plain-patch keys\n * AND nested values inside `$set` / `$setOnInsert` operator objects. Operator\n * forms beyond those two are left untouched (their semantics differ).\n */\nexport const stripUndefinedFromUpdate = <T>(update: T): T => {\n if (update === null || typeof update !== 'object') return update;\n const doc = update as Record<string, unknown>;\n\n for (const operator of ['$set', '$setOnInsert']) {\n const op = doc[operator];\n if (op !== null && typeof op === 'object' && !Array.isArray(op)) {\n const opDoc = op as Record<string, unknown>;\n for (const key of Object.keys(opDoc)) {\n if (opDoc[key] === undefined) delete opDoc[key];\n }\n }\n }\n\n for (const key of Object.keys(doc)) {\n if (doc[key] === undefined) delete doc[key];\n }\n return update;\n};\n","/**\n * Shared schema-drift checker for the read path.\n *\n * Checks freshly-fetched documents (the result of an actual DB round-trip,\n * not a cache hit) against their declared schema and either logs the drift\n * (`'report'` mode) or throws a typed `DomainError SCHEMA_DRIFT` (`'throw'`).\n * Detection-only — never mutates the documents.\n */\nimport type { Document } from 'mongodb';\nimport { DomainError } from '../errors/index.ts';\nimport type { ObjectField } from '../schema/types.ts';\nimport { type DriftMode, validateDoc } from '../schema/validate-doc/index.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\n\nexport interface DriftCheckerOptions {\n logger: LoggerLike;\n /** DB label for error/log context. */\n db: string;\n /** Effective drift mode for this read (already resolved from per-op + service). */\n drift: DriftMode;\n /** Resolve the declared schema for a logical collection. */\n getSchema?: (logical: string) => ObjectField | undefined;\n}\n\n/**\n * Validate `docs` against the collection schema and react per the drift mode.\n * No-op when `drift` is `'off'`, the collection has no schema, or the docs are\n * all conformant.\n */\nexport const checkDocsDrift = (\n options: DriftCheckerOptions,\n collection: string,\n op: string,\n docs: Document[],\n): void => {\n if (options.drift === 'off') return;\n const schema = options.getSchema?.(collection);\n if (!schema) return;\n for (const doc of docs) {\n const issues = validateDoc(schema, doc);\n if (issues.length === 0) continue;\n const detail = issues.map((i) => `${i.path}: ${i.message}`).join('; ');\n const extra = { collection, db: options.db, op, issues };\n if (options.drift === 'throw') {\n throw new DomainError(\n 'SCHEMA_DRIFT',\n `Document drifted from schema in \"${collection}\": ${detail}`,\n extra,\n );\n }\n options.logger.warn(extra, `[drift] ${collection} (${options.db}, ${op}): ${detail}`);\n }\n};\n","import type { Document, UpdateFilter } from 'mongodb';\nimport type { UpdateInput } from './update-types.ts';\n\n/** True when `update` uses `$`-operator syntax (vs a plain field patch). */\nexport const hasUpdateOperator = (update?: UpdateFilter<Record<string, unknown>>): boolean => {\n if (!update) return false;\n return Object.keys(update).some((key) => key.startsWith('$'));\n};\n\n/**\n * Normalize an update payload: a plain object (e.g. `{ name: 'x' }`) becomes\n * `{ $set: { name: 'x' } }`; documents already using `$` operators pass through\n * unchanged. Used by `upsert` / `bulkUpsert`.\n */\nexport const formatUpdateFilter = <T extends Document>(update: UpdateInput<T>): UpdateFilter<T> => {\n if (hasUpdateOperator(update as UpdateFilter<Record<string, unknown>>)) {\n return update as UpdateFilter<T>;\n }\n return { $set: update } as UpdateFilter<T>;\n};\n","/**\n * Shared CRUD context: the cross-cutting helpers every CRUD op group depends\n * on (collection resolution, tracing, retry plumbing, cache/dedup/drift read\n * pipeline, auto-timestamps, `select` normalization).\n *\n * `makeCrudOps` (see `./index.ts`) builds ONE context via `createCrudContext`\n * and hands it to the read / write / watch op-group factories, so the helpers\n * live in exactly one place instead of being duplicated per op. This module is\n * the dependency-injection seam of the CRUD layer.\n */\nimport type { Collection, Db, Document, Filter, FindOptions } from 'mongodb';\nimport type { InFlight } from '../../cache/in-flight.ts';\nimport type { QueryCache } from '../../cache/query-cache.ts';\nimport { cacheCollectionKey } from '../../cache/query-cache.ts';\nimport type { HooksRegistry } from '../../hooks/hooks.ts';\nimport { withRetry } from '../../mongo-helpers.ts';\nimport { applySchemaDefaults } from '../../schema/apply-defaults.ts';\nimport type { ObjectField } from '../../schema/types.ts';\nimport type { DriftMode } from '../../schema/validate-doc/index.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport type {\n CollectionTimestamps,\n DbClientsDefinition,\n ExtractCollectionNames,\n ExtractCollectionType,\n ExtractDbNames,\n} from '../../types.ts';\nimport { stableHash } from '../../utils/hash.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { stripUndefinedFromUpdate, stripUndefinedKeys } from '../../utils/omit-undefined.ts';\nimport { defineCrudOp } from '../crud-op.ts';\nimport { checkDocsDrift } from '../drift.ts';\nimport { makeOpDeps } from '../op-deps.ts';\nimport {\n type QueryOptions,\n type ResolvedQueryOptions,\n resolveDriftMode,\n resolveQueryOptions,\n} from '../query-options.ts';\nimport type { DbOpMeta } from '../trace-db-op.ts';\nimport { formatUpdateFilter } from '../update-format.ts';\nimport type { UpdateInput } from '../update-types.ts';\n\nexport type ColNames<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> = ExtractCollectionNames<TClients, TDb>;\n\nexport type DocOf<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n C extends ColNames<TClients, TDb>,\n> = ExtractCollectionType<TClients, TDb, C>;\n\n/** Input accepted by insert ops: the doc without `_id`, or with an explicit `_id`. */\nexport type InsertInput<T> = Omit<T, '_id'> & { _id?: T extends { _id: infer I } ? I : never };\n\nexport type VersionedUpdateResult<T> =\n | { ok: true; doc: T }\n | { ok: false; reason: 'not_found' | 'version_conflict' };\n\n/**\n * Find-query options. Extends driver `FindOptions` + SDK `QueryOptions` with a\n * first-class `select` (field list) that is translated to a driver `projection`\n * so only the requested fields are transferred from the server.\n */\nexport type FindQueryOptions<T> = FindOptions &\n QueryOptions & {\n /** Project only the listed fields — pushed to the driver as `projection`. */\n select?: readonly (keyof T)[];\n };\n\n/** Per-collection auto-timestamp config (keyed by logical collection name). */\nexport type TimestampsByCollection = Record<string, CollectionTimestamps | undefined>;\n\nexport interface CrudOpsOptions {\n resolveCollectionName: (logical: string) => string;\n wrapMongoErrors?: boolean;\n cache?: QueryCache;\n dedupeReads?: boolean;\n inFlight?: InFlight;\n hooks?: HooksRegistry;\n /** Auto-timestamp field names per collection (from the collection definition). */\n timestamps?: TimestampsByCollection;\n /** Service-level schema-drift policy for reads (default `'report'`). */\n drift?: DriftMode;\n /** Resolve the declared schema for a logical collection (drift detection). */\n getSchema?: (logical: string) => ObjectField | undefined;\n}\n\n/**\n * Everything a CRUD op-group factory needs, bundled into one immutable object.\n * See `createCrudContext` for the wiring.\n */\nexport interface CrudContext<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> {\n client: Db;\n dbLabel: string;\n logger: LoggerLike;\n opts: CrudOpsOptions;\n /** Logical → physical collection name. */\n resolve: (logical: string) => string;\n /** Trace + optional error mapping for a single DB call. */\n trace: <T>(meta: DbOpMeta, fn: () => T | Promise<T>) => Promise<T>;\n /** Structured log metadata for a (collection, op). */\n meta: (collection: ColNames<TClients, TDb>, op: string) => DbOpMeta;\n /** Raw driver collection handle for a logical collection. */\n coll: <X extends ColNames<TClients, TDb>>(name: X) => Collection<DocOf<TClients, TDb, X>>;\n /** Narrow the strict public filter to the driver's loose `Filter<T>`. */\n toDriverFilter: <X extends ColNames<TClients, TDb>>(\n filter: FilterInput<DocOf<TClients, TDb, X>>,\n ) => Filter<DocOf<TClients, TDb, X>>;\n /** Op pipeline (resolve → trace → retry) for reads. */\n run: <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n options?: QueryOptions,\n /** What was sent to the DB — recorded in the debugbar as the span's params. */\n params?: unknown,\n ) => Promise<T>;\n /** Op pipeline for writes — transient errors retried only with `retryWrites: true`. */\n writeRun: <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n options?: QueryOptions,\n params?: unknown,\n ) => Promise<T>;\n /** Drop this collection's cached reads (DB-namespaced key). */\n invalidate: (collection: ColNames<TClients, TDb>) => void;\n /** Stamp `createdAt`/`updatedAt` onto a doc being created (in place, only when unset). */\n stampCreate: (collection: ColNames<TClients, TDb>, doc: Document) => void;\n /** Merge `updatedAt` into an update payload (plain patch or `$set` operator form). */\n stampUpdate: <X extends ColNames<TClients, TDb>>(\n collection: X,\n update: UpdateInput<DocOf<TClients, TDb, X>>,\n ) => UpdateInput<DocOf<TClients, TDb, X>>;\n /** Return a full replacement with `updatedAt` stamped. */\n stampReplace: (collection: ColNames<TClients, TDb>, doc: Document) => Document;\n /** Shared read pipeline: trace + retry, with opt-in cache and in-flight dedup. */\n read: <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n filter: FilterInput<DocOf<TClients, TDb, X>>,\n options: QueryOptions | undefined,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n shape?: 'one' | 'many' | 'none',\n /** Extra key discriminator (e.g. `distinct`'s field name). */\n keyExtra?: string,\n ) => Promise<T>;\n /** Translate `select` (field list) into a driver `projection`; strip `select`. */\n normalizeFindOptions: <T>(options: FindQueryOptions<T> | undefined) => FindOptions & QueryOptions;\n}\n\n/**\n * Build the CRUD shared context. All state is closure-local (no module-level\n * mutation) and handed to the op-group factories for composition.\n */\nexport const createCrudContext = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n client: Db,\n dbLabel: string,\n logger: LoggerLike,\n opts: CrudOpsOptions,\n): CrudContext<TClients, TDb> => {\n const resolve = opts.resolveCollectionName;\n const deps = makeOpDeps<ColNames<TClients, TDb>>(\n logger,\n dbLabel,\n resolve,\n opts.wrapMongoErrors === true,\n );\n const coll = <X extends ColNames<TClients, TDb>>(name: X): Collection<DocOf<TClients, TDb, X>> =>\n client.collection<DocOf<TClients, TDb, X>>(resolve(String(name)));\n const toDriverFilter = <X extends ColNames<TClients, TDb>>(\n filter: FilterInput<DocOf<TClients, TDb, X>>,\n ): Filter<DocOf<TClients, TDb, X>> => filter as unknown as Filter<DocOf<TClients, TDb, X>>;\n const run = <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n options?: QueryOptions,\n params?: unknown,\n ): Promise<T> => defineCrudOp(deps, collection, opName, execute, options, false, params);\n\n /** Same as `run` but for write ops — transient errors are NOT auto-retried\n * unless the caller opts in via `QueryOptions.retryWrites` (at-least-once). */\n const writeRun = <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n options?: QueryOptions,\n params?: unknown,\n ): Promise<T> => defineCrudOp(deps, collection, opName, execute, options, true, params);\n\n const invalidate = (collection: ColNames<TClients, TDb>): void => {\n // Namespaced by DB so a write to one database never (in)validates another's\n // same-named collection in the shared cache.\n opts.cache?.invalidateByCollection(\n cacheCollectionKey(client.databaseName, resolve(String(collection))),\n );\n };\n\n const timestampsFor = (collection: ColNames<TClients, TDb>): CollectionTimestamps | undefined =>\n opts.timestamps?.[String(collection)];\n\n /**\n * Normalize + stamp a doc being created (in place): schema defaults are\n * materialized first (absent defaulted fields get their declared value),\n * `undefined` keys are stripped (TS \"absent\" must not serialize to `null`\n * under a strict validator) and `createdAt`/`updatedAt` are set when unset.\n */\n const stampCreate = (collection: ColNames<TClients, TDb>, doc: Document): void => {\n applySchemaDefaults(opts.getSchema?.(String(collection)), doc);\n stripUndefinedKeys(doc);\n const ts = timestampsFor(collection);\n if (!ts) return;\n const now = new Date();\n if (ts.createdAt && doc[ts.createdAt] === undefined) doc[ts.createdAt] = now;\n if (ts.updatedAt && doc[ts.updatedAt] === undefined) doc[ts.updatedAt] = now;\n };\n\n /** Normalize + merge `updatedAt` into an update payload (plain patch or `$set` operator form). */\n const stampUpdate = <X extends ColNames<TClients, TDb>>(\n collection: X,\n update: UpdateInput<DocOf<TClients, TDb, X>>,\n ): UpdateInput<DocOf<TClients, TDb, X>> => {\n // `undefined` = absent, never `null` on the wire (see omit-undefined).\n stripUndefinedFromUpdate(update);\n // Always normalize plain patches into `$set` form (matches `formatUpdateFilter`).\n const formatted = formatUpdateFilter(update) as Document & { $set?: Document };\n const ts = timestampsFor(collection);\n if (ts?.updatedAt) {\n const $set = { ...(formatted.$set as Document | undefined), [ts.updatedAt]: new Date() };\n return { ...formatted, $set } as unknown as UpdateInput<DocOf<TClients, TDb, X>>;\n }\n return formatted as unknown as UpdateInput<DocOf<TClients, TDb, X>>;\n };\n\n /** Return a full replacement with `updatedAt` stamped (findOneAndReplace/replaceOne). */\n const stampReplace = (collection: ColNames<TClients, TDb>, doc: Document): Document => {\n applySchemaDefaults(opts.getSchema?.(String(collection)), doc);\n stripUndefinedKeys(doc);\n const ts = timestampsFor(collection);\n if (!ts?.updatedAt) return doc;\n return { ...doc, [ts.updatedAt]: new Date() };\n };\n\n /** Shared read pipeline: trace + retry, with opt-in cache and in-flight dedup. */\n const read = async <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n filter: FilterInput<DocOf<TClients, TDb, X>>,\n options: QueryOptions | undefined,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n shape: 'one' | 'many' | 'none' = 'none',\n keyExtra?: string,\n ): Promise<T> => {\n const physical = resolve(String(collection));\n const resolved = resolveQueryOptions(options);\n // What was sent to the DB, surfaced in the debugbar as the span's `params`:\n // the filter plus any driver options (sort/limit/projection/…) and, for\n // `distinct`, the field. `driverOpts` is session-free by construction\n // (session is stripped into `resolved.sdk`), so it is safe to capture.\n const sentParams: Record<string, unknown> = { filter };\n if (Object.keys(resolved.driverOpts).length > 0) sentParams.options = resolved.driverOpts;\n if (keyExtra !== undefined) sentParams.field = keyExtra;\n const noSession = !resolved.sdk.session;\n const useCache = opts.cache !== undefined && noSession && resolved.cache !== false;\n const shouldDedupe =\n resolved.dedupe !== false &&\n (resolved.dedupe === true || (opts.dedupeReads === true && noSession)) &&\n opts.inFlight !== undefined;\n\n // Schema-drift detection on DB fetch only: check the freshly-fetched docs\n // BEFORE they are cached, so `'throw'` mode never caches/exposes a drifted\n // document and `'report'` mode logs once per fetch (cache hits are skipped).\n // Projected reads return partial documents — validation would false-positive\n // on the excluded required fields, so they are skipped.\n const checkDrift = (value: T): void => {\n const mode = resolveDriftMode(resolved.sdk.drift, opts.drift);\n if (mode === 'off') return;\n if ((resolved.driverOpts as { projection?: unknown }).projection !== undefined) return;\n const docs: Document[] =\n shape === 'many'\n ? (value as Document[])\n : shape === 'one' && value !== null\n ? [value as Document]\n : [];\n checkDocsDrift(\n {\n logger,\n db: dbLabel,\n drift: mode,\n ...(opts.getSchema !== undefined ? { getSchema: opts.getSchema } : {}),\n },\n String(collection),\n opName,\n docs,\n );\n };\n\n const executeWrapped = () =>\n deps.trace(deps.meta(collection, opName, sentParams), () =>\n withRetry(() => execute(resolved), {\n maxAttempts: resolved.maxAttempts,\n delayMs: resolved.retryDelayMs,\n }),\n );\n\n // Hash ONCE and reuse for both the cache key and the dedup key.\n // The op name is part of the identity — `getOne`/`countDocuments`/`distinct`\n // on the same filter return different SHAPES, so they must never share a\n // cache entry (`distinct` also namespaces by its field). Pure retry/dedup\n // knobs are stripped so they can't fragment the cache; `drift` STAYS\n // because it changes read SEMANTICS (a 'throw' request must never be\n // served an entry that was cached under 'off'/'report' without\n // validation), and everything result-affecting (driver opts, session)\n // stays too. Computed LAZILY: session reads use neither cache nor dedup,\n // so their options (containing cyclic ClientSession objects) are never\n // serialized at all.\n const {\n maxAttempts: _ma,\n retryDelayMs: _rd,\n dedupe: _dd,\n cache: _ca,\n retryWrites: _rw,\n ...resultOptions\n } = (options ?? {}) as QueryOptions;\n void _ma;\n void _rd;\n void _dd;\n void _ca;\n void _rw;\n let payloadHash: string | undefined;\n const getPayloadHash = (): string => {\n if (payloadHash === undefined) {\n payloadHash = stableHash([opName, keyExtra ?? '', filter, resultOptions]);\n }\n return payloadHash;\n };\n\n const key = useCache\n ? opts.cache!.key(cacheCollectionKey(client.databaseName, physical), getPayloadHash())\n : undefined;\n\n // Execution is created lazily so in-flight dedup can share ONE underlying\n // driver call (creating it eagerly would start a call per request).\n const fetchAndCheck = (): Promise<T> =>\n executeWrapped().then((value) => {\n checkDrift(value);\n return value;\n });\n\n const runOnce = (): Promise<T> => {\n if (useCache && key) {\n // Capture the collection version BEFORE fetching so a write that lands\n // mid-flight can never be hidden by a late cache set (see `get` guard).\n const colKey = cacheCollectionKey(client.databaseName, physical);\n const versions = { [colKey]: opts.cache!.versionOf(colKey) };\n const hit = opts.cache!.get(key) as T | undefined;\n if (hit !== undefined) return Promise.resolve(hit);\n return fetchAndCheck().then((value) => {\n opts.cache!.set(key, value, undefined, undefined, versions);\n return value;\n });\n }\n return fetchAndCheck();\n };\n\n if (shouldDedupe) {\n // The collection VERSION is part of the dedup identity: a reader arriving\n // after a write invalidated the collection must start a FRESH load, never\n // join the pre-invalidation in-flight promise (mirrors HotCache's gen).\n const colKey = cacheCollectionKey(client.databaseName, physical);\n const gen = opts.cache !== undefined ? opts.cache.versionOf(colKey) : '';\n // `await` (not a bare `return`): a non-awaited return from this async\n // function unwinds the caller chain in Bun's stack capture, so the ignex\n // debugbar's span origin would truncate here and never reach the route\n // handler that issued this read.\n return await opts.inFlight!.run(`${colKey}|${gen}|${getPayloadHash()}`, runOnce);\n }\n return await runOnce();\n };\n\n /** Translate `select` (field list) into a driver `projection`; strip `select`. */\n const normalizeFindOptions = <T>(\n options: FindQueryOptions<T> | undefined,\n ): FindOptions & QueryOptions => {\n if (!options) return {};\n const { select, ...rest } = options;\n if (!select || select.length === 0) return rest;\n const projection: Record<string, 1> = {};\n for (const field of select) projection[String(field)] = 1;\n return { ...rest, projection };\n };\n\n return {\n client,\n dbLabel,\n logger,\n opts,\n resolve,\n trace: deps.trace,\n meta: deps.meta,\n coll,\n toDriverFilter,\n run,\n writeRun,\n invalidate,\n stampCreate,\n stampUpdate,\n stampReplace,\n read,\n normalizeFindOptions,\n };\n};\n","import type { Document, Filter } from 'mongodb';\nimport type { FilterInput } from './filter-types.ts';\n\n/**\n * Soft-delete support. A soft-deleted row is one where `deletedAt` exists and is\n * non-null. Mirrors sdk-db's `crud-shared/soft-delete.ts`.\n */\nexport const buildMongoActiveFilter = (): Filter<Document> =>\n ({ $or: [{ deletedAt: { $exists: false } }, { deletedAt: null }] }) as Filter<Document>;\n\n/**\n * Merge a caller filter with the soft-delete \"active\" filter.\n * - softDelete=false → the caller filter unchanged\n * - empty/absent filter → active filter alone\n * - otherwise → `{ $and: [filter, active] }`\n */\nexport const mergeMongoActiveFilter = <T extends Document>(\n softDelete: boolean,\n filter?: FilterInput<T> | Filter<T>,\n): Filter<T> => {\n if (!softDelete) return (filter ?? {}) as Filter<T>;\n const active = buildMongoActiveFilter() as Filter<T>;\n if (!filter || Object.keys(filter).length === 0) return active;\n return { $and: [filter, active] } as Filter<T>;\n};\n","/**\n * Read op group: every CRUD query that goes through the shared cache + dedup +\n * drift pipeline (`getOne`, `findMany`, `findActive*`, `countDocuments`,\n * `distinct`, `estimatedDocumentCount`).\n *\n * A pure function of the shared `CrudContext` — composed into `makeCrudOps`\n * (see `./index.ts`). No mutable state beyond what the context closes over.\n */\nimport type {\n CountDocumentsOptions,\n DistinctOptions,\n Document,\n EstimatedDocumentCountOptions,\n FindCursor,\n FindOptions,\n} from 'mongodb';\nimport { DomainError } from '../../errors/index.ts';\nimport { hasHook, runHooks } from '../../hooks/hooks.ts';\nimport { DEFAULT_FIND_LIMIT } from '../../shared/constants.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport { mergeMongoActiveFilter } from '../../shared/soft-delete.ts';\nimport { cloneDeep } from '../../utils/clone.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type { ColNames, CrudContext, DocOf, FindQueryOptions } from './context.ts';\n\n/** Read ops produced for one database by `makeReadOps`. */\nexport type ReadOps<\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n> = ReturnType<typeof makeReadOps<TClients, TDb>>;\n\n/**\n * Build the read op set from the shared CRUD context. `getOne`/`findMany` are\n * returned (and internally referenced) so write ops can reuse them, e.g.\n * `updateWithVersion`'s cache-bypassing version read.\n */\nexport const makeReadOps = <\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n>(\n ctx: CrudContext<TClients, TDb>,\n) => {\n type C = ColNames<TClients, TDb>;\n type DocOf2<X extends C> = DocOf<TClients, TDb, X>;\n\n const { opts } = ctx;\n const { coll, toDriverFilter, read, normalizeFindOptions } = ctx;\n\n /** Fetch a single document by filter, or `null` when none matches. Cached + deduped. */\n const getOne = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): Promise<DocOf2<X> | null> => {\n const f = filter ?? {};\n const o = normalizeFindOptions(options);\n const doc = await read(\n collection,\n 'mongo.getOne',\n f,\n o,\n async (r) => {\n const opts: FindOptions = {\n ...(r.driverOpts as FindOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n };\n return (await coll(collection).findOne(\n toDriverFilter(f),\n opts,\n )) as unknown as DocOf2<X> | null;\n },\n 'one',\n );\n if (doc !== null && hasHook(opts.hooks, String(collection), 'afterRead')) {\n // Isolate hook mutation from the shared cache entry: hooks receive a\n // clone so mutating `ctx.doc` can't poison the cached document (which\n // stays pristine for every subsequent cache hit).\n const exposed = cloneDeep(doc) as DocOf2<X>;\n await runHooks(opts.hooks, String(collection), 'afterRead', {\n collection: String(collection),\n doc: exposed,\n });\n return exposed;\n }\n return doc;\n };\n\n /** Fetch a single document or throw `DomainError NOT_FOUND`. Accepts an optional custom error factory. */\n const getOneOrFail = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n errorFactory?: (name: string) => Error,\n ): Promise<DocOf2<X>> => {\n const doc = await getOne(collection, filter, options);\n if (doc === null) {\n if (errorFactory) throw errorFactory(String(collection));\n throw new DomainError(\n 'NOT_FOUND',\n `Document not found in collection \"${String(collection)}\"`,\n {\n collection: String(collection),\n },\n );\n }\n return doc;\n };\n\n /** Fetch many documents (default limit `DEFAULT_FIND_LIMIT`). Cached + deduped. */\n const findMany = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): Promise<DocOf2<X>[]> => {\n const merged = normalizeFindOptions({\n ...options,\n limit: options?.limit ?? DEFAULT_FIND_LIMIT,\n });\n const docs = await read(\n collection,\n 'mongo.findMany',\n filter ?? {},\n merged,\n async (r) => {\n const opts: FindOptions = {\n ...(r.driverOpts as FindOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n };\n return coll(collection)\n .find(toDriverFilter(filter ?? {}), opts)\n .toArray() as unknown as DocOf2<X>[];\n },\n 'many',\n );\n if (hasHook(opts.hooks, String(collection), 'afterRead')) {\n const exposed = cloneDeep(docs) as DocOf2<X>[];\n await runHooks(opts.hooks, String(collection), 'afterRead', {\n collection: String(collection),\n docs: exposed as Document[],\n });\n return exposed;\n }\n return docs;\n };\n\n /** Return a raw driver cursor (caller-owned — must be iterated/closed). No cache/dedup. */\n const findManyCursor = <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): FindCursor<DocOf2<X>> => {\n const {\n session,\n hint,\n maxTimeMS,\n batchSize,\n maxAttempts: _ma,\n retryDelayMs: _rd,\n dedupe: _d,\n cache: _c,\n ...rest\n } = normalizeFindOptions(options);\n const findOpts: FindOptions = {\n ...(rest as FindOptions),\n ...(session && { session }),\n ...(hint && { hint }),\n ...(maxTimeMS && { maxTimeMS }),\n ...(batchSize && { batchSize }),\n };\n return coll(collection).find(toDriverFilter(filter ?? {}), findOpts) as unknown as FindCursor<\n DocOf2<X>\n >;\n };\n\n /** Find many non-soft-deleted docs (merges the active filter automatically). */\n const findActive = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): Promise<DocOf2<X>[]> =>\n findMany(collection, mergeMongoActiveFilter(true, filter) as FilterInput<DocOf2<X>>, options);\n\n /** Find one non-soft-deleted doc (merges the active filter automatically). */\n const findActiveOne = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): Promise<DocOf2<X> | null> =>\n getOne(collection, mergeMongoActiveFilter(true, filter) as FilterInput<DocOf2<X>>, options);\n\n /** Count documents matching a filter. Cached + deduped. */\n const countDocuments = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: CountDocumentsOptions & QueryOptions,\n ): Promise<number> =>\n read(\n collection,\n 'mongo.countDocuments',\n filter ?? {},\n options,\n async (r) => {\n const opts: CountDocumentsOptions = {\n ...(r.driverOpts as CountDocumentsOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n };\n return await coll(collection).countDocuments(toDriverFilter(filter ?? {}), opts);\n },\n 'none',\n );\n\n /** Distinct values of `field` (schema-typed); routed through cache + dedup. */\n const distinct = async <X extends C, K extends keyof DocOf2<X>>(\n collection: X,\n field: K,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): Promise<Array<DocOf2<X>[K]>> => {\n const f = filter ?? {};\n const o = normalizeFindOptions(options);\n return read(\n collection,\n 'mongo.distinct',\n f,\n o,\n async (r) => {\n const opts: FindOptions = {\n ...(r.driverOpts as FindOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n };\n return coll(collection).distinct(\n String(field),\n toDriverFilter(f),\n opts as DistinctOptions,\n ) as unknown as Array<DocOf2<X>[K]>;\n },\n 'none',\n String(field),\n );\n };\n\n /** Approximate collection count from metadata (fast, not filter-aware). Cached + deduped. */\n const estimatedDocumentCount = async <X extends C>(\n collection: X,\n options?: EstimatedDocumentCountOptions & QueryOptions,\n ): Promise<number> =>\n read(\n collection,\n 'mongo.estimatedDocumentCount',\n {},\n options,\n async (r) => {\n const opts: EstimatedDocumentCountOptions = {\n ...(r.driverOpts as EstimatedDocumentCountOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n };\n return await coll(collection).estimatedDocumentCount(opts);\n },\n 'none',\n );\n\n return {\n getOne,\n getOneOrFail,\n findMany,\n findManyCursor,\n findActive,\n findActiveOne,\n countDocuments,\n distinct,\n estimatedDocumentCount,\n };\n};\n","/**\n * Watch/query-builder op group: `watchCollection` (caller-owned change stream)\n * and `query` (the fluent `QueryBuilder` entry point, whose reads flow through\n * the shared cache + dedup pipeline).\n *\n * Composed into `makeCrudOps` (see `./index.ts`).\n */\nimport type { ChangeStream, ChangeStreamOptions, Document, FindOptions } from 'mongodb';\nimport { QueryBuilder } from '../../query-builder/query-builder.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type { ColNames, CrudContext, DocOf } from './context.ts';\n\n/** Watch/query ops produced for one database by `makeWatchOps`. */\nexport type WatchOps<\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n> = ReturnType<typeof makeWatchOps<TClients, TDb>>;\n\n/** Build the watch + query-builder op set from the shared CRUD context. */\nexport const makeWatchOps = <\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n>(\n ctx: CrudContext<TClients, TDb>,\n) => {\n type C = ColNames<TClients, TDb>;\n type DocOf2<X extends C> = DocOf<TClients, TDb, X>;\n\n const { client, resolve, coll, read } = ctx;\n\n /**\n * Open a change stream on a collection. The returned `ChangeStream` is owned\n * by the caller — attach an `'error'` listener and call `.close()` when done\n * so a fire-and-forget stream never becomes an unhandled rejection.\n */\n const watchCollection = <X extends C>(\n collection: X,\n pipeline?: Document[],\n options?: ChangeStreamOptions,\n ): ChangeStream<DocOf2<X>> => coll(collection).watch(pipeline, options);\n\n /** Fluent query builder entry point. Reads flow through the cache + dedup pipeline. */\n const query = <X extends C>(collection: X): QueryBuilder<DocOf2<X>> => {\n const physical = resolve(String(collection));\n const handle = client.collection<DocOf2<X>>(physical);\n return new QueryBuilder<DocOf2<X>>({\n physicalName: physical,\n collection: handle,\n run: async <T>(\n opName: string,\n filter: FilterInput<DocOf2<X>>,\n execute: (driverOpts: FindOptions) => Promise<T>,\n options?: QueryOptions,\n ): Promise<T> =>\n read(\n collection,\n opName,\n filter,\n options,\n async (r) => {\n const opts: FindOptions = {\n ...(r.driverOpts as FindOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n };\n return await execute(opts);\n },\n opName === 'mongo.getOne' ? 'one' : opName === 'mongo.findMany' ? 'many' : 'none',\n ),\n });\n };\n\n return {\n watchCollection,\n query,\n };\n};\n","/**\n * Write op group: every mutating CRUD operation. All writes invalidate the\n * collection's cache and fire lifecycle hooks (`beforeUpdate`/`afterUpdate`\n * on update-shaped ops including `updateMany`/`findOneAndUpdate`/`upsert`,\n * `beforeDelete`/`afterDelete` on delete-shaped ops including `deleteMany`\n * and `softDeleteOne`). The two RAW escape hatches (`bulkWrite`, and the\n * per-operation nature of `bulkUpsert`) are hook-translucent by design —\n * there is no single filter/doc to hand a hook. Transient driver errors are\n * retried only when the caller opts in via `QueryOptions.retryWrites`\n * (at-least-once semantics).\n *\n * Composed into `makeCrudOps` (see `./index.ts`). Takes the read ops object as\n * an explicit dependency so `updateWithVersion` can reuse `getOne` for its\n * cache-bypassing version read — dependency injection rather than a shared\n * closure.\n */\nimport type {\n AnyBulkWriteOperation,\n BulkWriteOptions,\n DeleteOptions,\n DeleteResult,\n Document,\n Filter,\n FindOneAndDeleteOptions,\n FindOneAndReplaceOptions,\n FindOneAndUpdateOptions,\n FindOptions,\n InsertManyResult,\n InsertOneOptions,\n InsertOneResult,\n OptionalUnlessRequiredId,\n ReplaceOptions,\n UpdateFilter,\n UpdateOptions,\n UpdateResult,\n} from 'mongodb';\nimport { BadRequest } from '../../errors/index.ts';\nimport { type HookContext, runHooks } from '../../hooks/hooks.ts';\nimport { MAX_BATCH_OPS } from '../../shared/constants.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport { mergeMongoActiveFilter } from '../../shared/soft-delete.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type { UpdateInput } from '../update-types.ts';\nimport type {\n ColNames,\n CrudContext,\n DocOf,\n InsertInput,\n VersionedUpdateResult,\n} from './context.ts';\nimport type { ReadOps } from './read-ops.ts';\n\n/** Write ops produced for one database by `makeWriteOps`. */\nexport type WriteOps<\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n> = ReturnType<typeof makeWriteOps<TClients, TDb>>;\n\n/**\n * Build the write op set from the shared CRUD context. `readOps.getOne` is\n * injected so versioned updates read committed state without the cache.\n */\nexport const makeWriteOps = <\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n>(\n ctx: CrudContext<TClients, TDb>,\n readOps: ReadOps<TClients, TDb>,\n) => {\n type C = ColNames<TClients, TDb>;\n type DocOf2<X extends C> = DocOf<TClients, TDb, X>;\n\n const { opts } = ctx;\n const { coll, toDriverFilter, writeRun, invalidate, stampCreate, stampUpdate, stampReplace } =\n ctx;\n const { getOne } = readOps;\n\n /**\n * Post-commit hook runner. `after*` hooks fire AFTER the DB write and cache\n * invalidation have succeeded — a throwing hook must NOT fail the operation:\n * the caller would see \"failed\" for already-committed state, and a retrying\n * caller would duplicate the write. Log loudly and keep the committed result.\n */\n const safeAfterHooks = async (\n collection: string,\n name: 'afterCreate' | 'afterUpdate' | 'afterDelete',\n hookCtx: HookContext<Document>,\n ): Promise<void> => {\n try {\n await runHooks(opts.hooks, collection, name, hookCtx);\n } catch (err) {\n ctx.logger.error?.(\n {\n collection,\n hook: name,\n error: err instanceof Error ? err.message : String(err),\n },\n `post-commit ${name} hook failed; DB write is already committed`,\n );\n }\n };\n\n /** Insert one document (runs before/after-create hooks; stamps timestamps; invalidates cache). */\n const insertOne = async <X extends C>(\n collection: X,\n doc: InsertInput<DocOf2<X>>,\n options?: InsertOneOptions & QueryOptions,\n ): Promise<InsertOneResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeCreate', {\n collection: String(collection),\n doc: doc as Document,\n });\n stampCreate(collection, doc as Document);\n const result = await writeRun(\n collection,\n 'mongo.insertOne',\n async (r) => {\n const insertOpts: InsertOneOptions = {\n ...(r.driverOpts as InsertOneOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return await coll(collection).insertOne(\n doc as OptionalUnlessRequiredId<DocOf2<X>>,\n insertOpts,\n );\n },\n options,\n { doc },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterCreate', {\n collection: String(collection),\n doc: doc as Document,\n });\n return result as InsertOneResult<DocOf2<X>>;\n };\n\n /** Insert many documents in one call (guards against batches over `MAX_BATCH_OPS`). */\n const insertMany = async <X extends C>(\n collection: X,\n docs: ReadonlyArray<InsertInput<DocOf2<X>>>,\n options?: BulkWriteOptions & QueryOptions,\n ): Promise<InsertManyResult<DocOf2<X>>> => {\n // Guard BEFORE stamping/hooking — don't pay O(n) work for an inevitable throw.\n if (docs.length > MAX_BATCH_OPS) {\n throw new BadRequest(\n `insertMany: too many docs (${docs.length} > ${MAX_BATCH_OPS}); split the batch`,\n );\n }\n await runHooks(opts.hooks, String(collection), 'beforeCreate', {\n collection: String(collection),\n docs: docs as unknown as Document[],\n });\n for (const d of docs) stampCreate(collection, d as Document);\n const result = await writeRun(\n collection,\n 'mongo.insertMany',\n async (r) => {\n const bulkOpts: BulkWriteOptions = {\n ...(r.driverOpts as BulkWriteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return coll(collection).insertMany(\n docs as ReadonlyArray<OptionalUnlessRequiredId<DocOf2<X>>>,\n bulkOpts,\n );\n },\n options,\n { docs },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterCreate', {\n collection: String(collection),\n docs: docs as unknown as Document[],\n });\n return result as InsertManyResult<DocOf2<X>>;\n };\n\n /** Update the first document matching a filter (runs before/after-update hooks). */\n const updateOne = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n update: UpdateInput<DocOf2<X>>,\n options?: UpdateOptions & QueryOptions,\n ): Promise<UpdateResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const effective = stampUpdate(collection, update);\n const result = await writeRun(\n collection,\n 'mongo.updateOne',\n async (r) => {\n const updateOpts: UpdateOptions = {\n ...(r.driverOpts as UpdateOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return coll(collection).updateOne(\n toDriverFilter(filter),\n effective as unknown as UpdateFilter<DocOf2<X>>,\n updateOpts,\n );\n },\n options,\n { filter, update: effective },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Update every document matching a filter (runs before/after-update hooks). */\n const updateMany = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n update: UpdateInput<DocOf2<X>>,\n options?: UpdateOptions & QueryOptions,\n ): Promise<UpdateResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const effective = stampUpdate(collection, update);\n const result = await writeRun(\n collection,\n 'mongo.updateMany',\n async (r) => {\n const updateOpts: UpdateOptions = {\n ...(r.driverOpts as UpdateOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return coll(collection).updateMany(\n toDriverFilter(filter),\n effective as unknown as UpdateFilter<DocOf2<X>>,\n updateOpts,\n );\n },\n options,\n { filter, update: effective },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Find one + update atomically (runs before/after-update hooks). */\n const findOneAndUpdate = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n update: UpdateInput<DocOf2<X>>,\n options?: FindOneAndUpdateOptions & QueryOptions,\n ): Promise<DocOf2<X> | null> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const effective = stampUpdate(collection, update);\n const result = await writeRun(\n collection,\n 'mongo.findOneAndUpdate',\n async (r) => {\n const fOpts = {\n ...(r.driverOpts as FindOneAndUpdateOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined\n ? { hint: r.sdk.hint as FindOneAndUpdateOptions['hint'] }\n : {}),\n // `after` is the ORM's default, but honor an explicit caller override.\n returnDocument: (r.driverOpts as FindOneAndUpdateOptions).returnDocument ?? 'after',\n } as FindOneAndUpdateOptions;\n return coll(collection).findOneAndUpdate(\n toDriverFilter(filter),\n effective as unknown as UpdateFilter<DocOf2<X>>,\n fOpts,\n ) as unknown as DocOf2<X> | null;\n },\n options,\n { filter, update: effective },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Find one + replace atomically with a full replacement doc (runs update hooks). */\n const findOneAndReplace = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n replacement: DocOf2<X>,\n options?: FindOneAndReplaceOptions & QueryOptions,\n ): Promise<DocOf2<X> | null> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const effective = stampReplace(collection, replacement as Document) as DocOf2<X>;\n const result = await writeRun(\n collection,\n 'mongo.findOneAndReplace',\n async (r) => {\n const fOpts = {\n ...(r.driverOpts as FindOneAndReplaceOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined\n ? { hint: r.sdk.hint as FindOneAndReplaceOptions['hint'] }\n : {}),\n // `after` is the ORM's default, but honor an explicit caller override.\n returnDocument: (r.driverOpts as FindOneAndReplaceOptions).returnDocument ?? 'after',\n } as FindOneAndReplaceOptions;\n return coll(collection).findOneAndReplace(\n toDriverFilter(filter),\n effective,\n fOpts,\n ) as unknown as DocOf2<X> | null;\n },\n options,\n { filter, replacement: effective },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Replace one document by filter (full replacement; runs before/after-update hooks). */\n const replaceOne = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n replacement: InsertInput<DocOf2<X>>,\n options?: ReplaceOptions & QueryOptions,\n ): Promise<UpdateResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const result = await writeRun(\n collection,\n 'mongo.replaceOne',\n async (r) => {\n const repOpts: ReplaceOptions = {\n ...(r.driverOpts as ReplaceOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return coll(collection).replaceOne(\n toDriverFilter(filter),\n stampReplace(collection, replacement as Document) as unknown as OptionalUnlessRequiredId<\n DocOf2<X>\n >,\n repOpts,\n );\n },\n options,\n { filter, replacement },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Delete the first document matching a filter (runs before/after-delete hooks). */\n const deleteOne = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n options?: DeleteOptions & QueryOptions,\n ): Promise<DeleteResult> => {\n await runHooks(opts.hooks, String(collection), 'beforeDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const result = await writeRun(\n collection,\n 'mongo.deleteOne',\n async (r) => {\n const delOpts: DeleteOptions = {\n ...(r.driverOpts as DeleteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return await coll(collection).deleteOne(toDriverFilter(filter), delOpts);\n },\n options,\n { filter },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Delete every document matching a filter (runs before/after-delete hooks). */\n const deleteMany = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n options?: DeleteOptions & QueryOptions,\n ): Promise<DeleteResult> => {\n await runHooks(opts.hooks, String(collection), 'beforeDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const result = await writeRun(\n collection,\n 'mongo.deleteMany',\n async (r) => {\n const delOpts: DeleteOptions = {\n ...(r.driverOpts as DeleteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return await coll(collection).deleteMany(toDriverFilter(filter), delOpts);\n },\n options,\n { filter },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Find one + delete atomically (runs before/after-delete hooks). */\n const findOneAndDelete = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n options?: FindOneAndDeleteOptions & QueryOptions,\n ): Promise<DocOf2<X> | null> => {\n await runHooks(opts.hooks, String(collection), 'beforeDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const result = await writeRun(\n collection,\n 'mongo.findOneAndDelete',\n async (r) => {\n const fOpts = {\n ...(r.driverOpts as FindOneAndDeleteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined\n ? { hint: r.sdk.hint as FindOneAndDeleteOptions['hint'] }\n : {}),\n } as FindOneAndDeleteOptions;\n return coll(collection).findOneAndDelete(\n toDriverFilter(filter),\n fOpts,\n ) as unknown as DocOf2<X> | null;\n },\n options,\n { filter },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /**\n * Soft-delete one doc: sets `deletedAt` instead of removing it (active reads\n * exclude it). Stamps `updatedAt` per the collection's timestamps config and\n * runs before/after-delete hooks — a soft delete IS a delete from the\n * lifecycle's point of view.\n */\n const softDeleteOne = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n options?: UpdateOptions & QueryOptions,\n ): Promise<UpdateResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const active = mergeMongoActiveFilter(true, filter);\n const effective = stampUpdate(collection, {\n $set: { deletedAt: new Date() },\n } as unknown as UpdateInput<DocOf2<X>>);\n const result = await writeRun(\n collection,\n 'mongo.softDeleteOne',\n async (r) => {\n const updateOpts: UpdateOptions = {\n ...(r.driverOpts as UpdateOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return coll(collection).updateOne(\n active,\n effective as unknown as UpdateFilter<DocOf2<X>>,\n updateOpts,\n );\n },\n options,\n { filter, update: effective },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Upsert one document (insert when the filter matches nothing; runs update hooks). */\n const upsert = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n update: UpdateInput<DocOf2<X>>,\n options?: UpdateOptions & QueryOptions,\n ): Promise<UpdateResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const formatted = stampUpdate(collection, update) as unknown as UpdateFilter<DocOf2<X>>;\n const result = await writeRun(\n collection,\n 'mongo.upsert',\n async (r) => {\n const updateOpts: UpdateOptions = {\n ...(r.driverOpts as UpdateOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n upsert: true,\n };\n return await coll(collection).updateOne(toDriverFilter(filter), formatted, updateOpts);\n },\n options,\n { filter, update: formatted },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Bulk upsert: many `updateOne`-style upserts in one write (guarded by `MAX_BATCH_OPS`). */\n const bulkUpsert = async <X extends C>(\n collection: X,\n operations: Array<{\n filter: FilterInput<DocOf2<X>>;\n update: UpdateInput<DocOf2<X>>;\n upsert?: boolean;\n }>,\n options?: BulkWriteOptions & QueryOptions,\n ): Promise<Document> => {\n // Guard BEFORE mapping/stamping — don't pay O(n) work for an inevitable throw.\n if (operations.length > MAX_BATCH_OPS) {\n throw new BadRequest(\n `bulkUpsert: too many operations (${operations.length} > ${MAX_BATCH_OPS}); split the batch`,\n );\n }\n const writes = operations.map((op) => ({\n updateOne: {\n filter: op.filter,\n update: stampUpdate(collection, op.update) as unknown as UpdateFilter<DocOf2<X>>,\n upsert: op.upsert ?? true,\n },\n })) as unknown as AnyBulkWriteOperation<DocOf2<X>>[];\n const result = await writeRun(\n collection,\n 'mongo.bulkUpsert',\n async (r) => {\n const bulkOpts: BulkWriteOptions = {\n ...(r.driverOpts as BulkWriteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return await coll(collection).bulkWrite(writes, bulkOpts);\n },\n options,\n { operations },\n );\n invalidate(collection);\n return result;\n };\n\n /** Generic `bulkWrite` with arbitrary driver bulk operations (guarded by `MAX_BATCH_OPS`). */\n const bulkWrite = async <X extends C>(\n collection: X,\n operations: AnyBulkWriteOperation<DocOf2<X>>[],\n options?: BulkWriteOptions & QueryOptions,\n ): Promise<Document> => {\n if (operations.length > MAX_BATCH_OPS) {\n throw new BadRequest(\n `bulkWrite: too many operations (${operations.length} > ${MAX_BATCH_OPS}); split the batch`,\n );\n }\n const result = await writeRun(\n collection,\n 'mongo.bulkWrite',\n async (r) => {\n const bulkOpts: BulkWriteOptions = {\n ...(r.driverOpts as BulkWriteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return await coll(collection).bulkWrite(operations, bulkOpts);\n },\n options,\n { operations },\n );\n invalidate(collection);\n return result;\n };\n\n /** Optimistic lock on a `__v` field: read → CAS update → version_conflict on miss. */\n const updateWithVersion = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n update: UpdateInput<DocOf2<X>>,\n options?: FindOneAndUpdateOptions & QueryOptions,\n ): Promise<VersionedUpdateResult<DocOf2<X>>> => {\n // The version read must reflect committed state — bypass the read cache\n // (a stale or cached-`null` entry would yield spurious not_found /\n // version_conflict even when the doc is present/current in the DB).\n const existing = await getOne(collection, filter, {\n ...(options as FindOptions & QueryOptions),\n cache: false,\n });\n if (!existing) return { ok: false, reason: 'not_found' };\n\n // A doc that has never been versioned has NO `__v` field — `{__v: 0}` would\n // never match, so match on the field's absence for the first write.\n const current = (existing as Document & { __v?: number }).__v;\n const versionFilter: Document =\n current === undefined ? { __v: { $exists: false } } : { __v: current };\n\n const formatted = stampUpdate(collection, update) as Document;\n const versionedUpdate = {\n ...formatted,\n $inc: { ...((formatted as Document).$inc as Document | undefined), __v: 1 },\n } as unknown as UpdateInput<DocOf2<X>>;\n\n const result = await findOneAndUpdate(\n collection,\n { ...filter, ...versionFilter } as unknown as FilterInput<DocOf2<X>>,\n versionedUpdate,\n { ...options, returnDocument: 'after' },\n );\n if (result === null) return { ok: false, reason: 'version_conflict' };\n return { ok: true, doc: result };\n };\n\n return {\n insertOne,\n insertMany,\n updateOne,\n updateMany,\n findOneAndUpdate,\n findOneAndReplace,\n deleteOne,\n deleteMany,\n softDeleteOne,\n upsert,\n bulkUpsert,\n bulkWrite,\n updateWithVersion,\n findOneAndDelete,\n replaceOne,\n };\n};\n","/**\n * CRUD op factory — `makeCrudOps` — and the public CRUD types.\n *\n * `makeCrudOps` is the composition root of the CRUD layer: it builds ONE shared\n * context (`createCrudContext` in `./context.ts`) and spreads the three op\n * groups it produces:\n *\n * - `makeReadOps` → every read op (cache/dedup/drift pipeline)\n * - `makeWriteOps` → every write op (hooks + timestamps + cache invalidation)\n * - `makeWatchOps` → change streams + fluent query builder\n *\n * The public surface (method names, signatures, exported types) is identical to\n * the historical single-file `crud.ts` — this is a pure organizational split.\n */\nimport type { Db } from 'mongodb';\nimport type { DbClientsDefinition, ExtractDbNames } from '../../types.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { type CrudOpsOptions, createCrudContext } from './context.ts';\nimport { makeReadOps } from './read-ops.ts';\nimport { makeWatchOps } from './watch-ops.ts';\nimport { makeWriteOps } from './write-ops.ts';\n\n/**\n * Build the CRUD operation set for one database. Every method is collection-name\n * first and schema-typed (no `<TDoc>` at call sites). Reads go through the\n * cache + in-flight dedup path; writes invalidate the cache for that collection\n * and fire lifecycle hooks.\n */\nexport const makeCrudOps = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n client: Db,\n dbLabel: string,\n logger: LoggerLike,\n opts: CrudOpsOptions,\n) => {\n const ctx = createCrudContext<TClients, TDb>(client, dbLabel, logger, opts);\n const readOps = makeReadOps<TClients, TDb>(ctx);\n return {\n ...readOps,\n ...makeWriteOps<TClients, TDb>(ctx, readOps),\n ...makeWatchOps<TClients, TDb>(ctx),\n };\n};\n\nexport type CrudOps<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> = ReturnType<typeof makeCrudOps<TClients, TDb>>;\n\n// Re-export the public CRUD types so `makeCrudOps` consumers get the full\n// surface from the folder barrel, matching the old single-module exports.\nexport type {\n CrudContext,\n CrudOpsOptions,\n FindQueryOptions,\n InsertInput,\n TimestampsByCollection,\n VersionedUpdateResult,\n} from './context.ts';\nexport type { ReadOps } from './read-ops.ts';\nexport type { WatchOps } from './watch-ops.ts';\nexport type { WriteOps } from './write-ops.ts';\n","/**\n * Keyset (cursor) pagination helpers — pure, DB-agnostic.\n *\n * Unlike offset pagination, keyset pagination filters on the *last seen* row's\n * sort values, so it stays O(log n) regardless of page depth (no deep `$skip`)\n * and is stable under concurrent inserts. It cannot report a total count —\n * use `paginateFlexible` ($facet) when you need totals.\n *\n * Requirement: every sort key (and the `_id` tiebreaker) should exist on every\n * document for deterministic ordering, since the boundary comparison relies on\n * them.\n */\n\nimport type { Document } from 'mongodb';\nimport { ObjectId } from 'mongodb';\nimport { BadRequest } from '../errors/index.ts';\n\n/** Serializable, tagged representation of a cursor boundary value. */\ntype TaggedValue = {\n t: 'oid' | 'date' | 'string' | 'number' | 'boolean' | 'null';\n v?: string | number | boolean;\n};\n\nexport interface KeysetCursor {\n /** The sort spec this cursor belongs to (used to reject mismatched cursors). */\n sort: Record<string, 1 | -1>;\n /** Boundary field values, in sort-key order. */\n values: unknown[];\n}\n\nconst tag = (value: unknown): TaggedValue => {\n if (value instanceof ObjectId) return { t: 'oid', v: value.toHexString() };\n if (value instanceof Date) return { t: 'date', v: value.toISOString() };\n if (typeof value === 'string') return { t: 'string', v: value };\n if (typeof value === 'number') return { t: 'number', v: value };\n if (typeof value === 'boolean') return { t: 'boolean', v: value };\n if (value === null || value === undefined) return { t: 'null' };\n // A drifted sort-field value (object/array/…) cannot be encoded losslessly\n // into a cursor — a `String(value)` fallback would silently corrupt\n // pagination (the decoded boundary could never compare against the real\n // field type). Fail loudly instead of serving a wrong page.\n throw new BadRequest(\n `paginateCursor: unsupported sort value type \"${typeof value}\" — key values must be ObjectId, Date, string, number, boolean, or null`,\n );\n};\n\nconst untag = (tagged: TaggedValue): unknown => {\n switch (tagged.t) {\n case 'oid':\n if (typeof tagged.v !== 'string') {\n throw new BadRequest('paginateCursor: invalid cursor — oid value must be a string');\n }\n return new ObjectId(tagged.v);\n case 'date':\n if (typeof tagged.v !== 'string') {\n throw new BadRequest('paginateCursor: invalid cursor — date value must be a string');\n }\n return new Date(tagged.v);\n case 'string':\n if (typeof tagged.v !== 'string') {\n throw new BadRequest('paginateCursor: invalid cursor — string value expected');\n }\n return tagged.v;\n case 'number':\n if (typeof tagged.v !== 'number') {\n throw new BadRequest('paginateCursor: invalid cursor — number value expected');\n }\n return tagged.v;\n case 'boolean':\n if (typeof tagged.v !== 'boolean') {\n throw new BadRequest('paginateCursor: invalid cursor — boolean value expected');\n }\n return tagged.v;\n case 'null':\n return null;\n }\n};\n\n/** Base64url-encode a cursor. The payload is opaque to callers. */\nexport const encodeCursor = (cursor: KeysetCursor): string =>\n Buffer.from(\n JSON.stringify({\n sort: cursor.sort,\n values: cursor.values.map(tag),\n }),\n 'utf8',\n ).toString('base64url');\n\n/** Decode + validate an opaque cursor. Throws on malformed input. */\nexport const decodeCursor = (cursor: string): KeysetCursor => {\n let parsed: { sort?: Record<string, 1 | -1>; values?: TaggedValue[] };\n try {\n parsed = JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8'));\n } catch {\n throw new BadRequest('paginateCursor: invalid cursor');\n }\n if (!parsed || typeof parsed !== 'object' || !parsed.sort || !Array.isArray(parsed.values)) {\n throw new BadRequest('paginateCursor: invalid cursor payload');\n }\n return { sort: parsed.sort, values: parsed.values.map(untag) };\n};\n\n/**\n * Build the keyset filter for the next page.\n *\n * Sort keys `[k1(d1), k2(d2), ...]` with boundary values `[v1, v2, ...]` produce\n * the standard disjunction of prefix-equalities plus a strict comparison on the\n * next key:\n *\n * k1 ≻ v1 OR (k1 = v1 AND k2 ≻ v2) OR ... OR (k1 = v1 AND ... AND kn ≻ vn)\n *\n * where `≻` is `>` for ascending keys and `<` for descending keys when\n * `direction` is `'after'` (inverted for `'before'`). `_id` is the natural\n * unique tiebreaker.\n */\nexport const buildKeysetFilter = (\n sort: Record<string, 1 | -1>,\n values: unknown[],\n direction: 'after' | 'before',\n): Document => {\n const keys = Object.entries(sort);\n const ors: Document[] = [];\n for (let i = 0; i < keys.length; i++) {\n const cond: Document = {};\n for (let j = 0; j < i; j++) {\n const [f] = keys[j]!;\n cond[f] = values[j];\n }\n const [field, dir] = keys[i]!;\n const value = values[i];\n const cmp = direction === 'after' ? (dir === 1 ? '$gt' : '$lt') : dir === 1 ? '$lt' : '$gt';\n cond[field] = { [cmp]: value };\n ors.push(cond);\n }\n return { $or: ors };\n};\n","/**\n * Keyset (cursor) pagination strategy — `paginateCursor`: O(log n) per page,\n * stable under concurrent writes, no total count. `after` walks forward from a\n * `nextCursor`; `before` walks backward by reversing the effective sort. Sort\n * must include a unique tiebreaker (`_id`).\n */\nimport type { Document, FindOptions } from 'mongodb';\nimport { BadRequest } from '../../errors/index.ts';\nimport { DEFAULT_FIND_LIMIT, DEFAULT_MAX_LIMIT } from '../../shared/constants.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport { buildKeysetFilter, decodeCursor, encodeCursor } from '../../shared/keyset.ts';\nimport { normalizePageLimit } from '../../shared/pagination-math.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport { defineCrudOp } from '../crud-op.ts';\nimport { checkDocsDrift } from '../drift.ts';\nimport { resolveDriftMode } from '../query-options.ts';\nimport type {\n CursorPage,\n CursorPaginationConfig,\n PaginationCtx,\n PaginationDocOf,\n} from './types.ts';\n\n/** Build the `paginateCursor` closure from the shared pagination context. */\nexport const makePaginateCursor = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: PaginationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = PaginationDocOf<TClients, TDb, X>;\n\n const { client, dbLabel, logger, opts, resolve, deps } = ctx;\n\n /**\n * Keyset (cursor) pagination — O(log n) per page, stable under concurrent\n * writes, no total count. `after` walks forward from a `nextCursor`;\n * `before` walks backward. Sort must include a unique tiebreaker (`_id`).\n */\n const paginateCursor = async <X extends C>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n config: CursorPaginationConfig,\n ): Promise<CursorPage<DocOf2<X>>> => {\n const sortKeys = Object.entries(config.sort);\n if (sortKeys.length === 0) {\n throw new BadRequest(\n 'paginateCursor: `sort` is required (include a unique tiebreaker like `_id`)',\n );\n }\n if (config.before !== undefined && config.after !== undefined) {\n throw new BadRequest('paginateCursor: provide either `after` or `before`, not both');\n }\n const limit = normalizePageLimit(\n { page: 1, ...(config.limit !== undefined ? { limit: config.limit } : {}) },\n config.maxLimit ?? DEFAULT_MAX_LIMIT,\n { limit: DEFAULT_FIND_LIMIT },\n ).limit;\n\n const backwards = config.before !== undefined && config.after === undefined;\n // In reversed space \"after the cursor\" == \"before the cursor\" in forward space.\n const effectiveSort: Record<string, 1 | -1> = backwards\n ? Object.fromEntries(sortKeys.map(([f, d]) => [f, (d * -1) as 1 | -1]))\n : config.sort;\n\n let filter: Document = baseFilter as Document;\n if (config.after !== undefined || config.before !== undefined) {\n const cursor = (config.after ?? config.before) as string;\n const decoded = decodeCursor(cursor);\n // Sort keys are ORDER-SENSITIVE: key precedence (primary/secondary/…)\n // defines the ordering, so a cursor built with a different key order is a\n // *different* sort and must be rejected — values are positional per key.\n if (JSON.stringify(decoded.sort) !== JSON.stringify(config.sort)) {\n throw new BadRequest('paginateCursor: cursor was created with a different sort');\n }\n if (decoded.values.length !== sortKeys.length) {\n throw new BadRequest('paginateCursor: cursor was created with a different sort');\n }\n filter = {\n $and: [baseFilter as Document, buildKeysetFilter(effectiveSort, decoded.values, 'after')],\n };\n }\n\n const rows = await defineCrudOp(\n deps,\n collection,\n 'mongo.paginateCursor',\n async (r) => {\n const findOpts: FindOptions = {\n ...(r.driverOpts as FindOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n ...(r.sdk.batchSize !== undefined ? { batchSize: r.sdk.batchSize } : {}),\n };\n return client\n .collection<Document>(resolve(String(collection)))\n .find(filter, findOpts)\n .sort(effectiveSort as Document)\n .limit(limit + 1)\n .toArray();\n },\n config.queryOptions,\n false,\n { filter, sort: effectiveSort, limit },\n );\n\n const hasMore = rows.length > limit;\n const page = backwards ? rows.slice(0, limit).reverse() : rows.slice(0, limit);\n checkDocsDrift(\n {\n logger,\n db: dbLabel,\n drift: resolveDriftMode(config.queryOptions?.drift, opts.drift),\n ...(opts.getSchema !== undefined ? { getSchema: opts.getSchema } : {}),\n },\n String(collection),\n 'mongo.paginateCursor',\n page as unknown as Document[],\n );\n const boundary = backwards ? rows[limit] : page[page.length - 1];\n let nextCursor: string | null = null;\n if (hasMore && boundary !== undefined) {\n const values = sortKeys.map(([f]) => (boundary as Document)[f]);\n if (values.some((v) => v === undefined)) {\n // A boundary doc missing a sort field would encode as `null`, whose\n // keyset comparison ALSO matches missing fields — pages could loop or\n // skip. Fail loudly instead of corrupting pagination.\n throw new BadRequest(\n 'paginateCursor: boundary document is missing a sort field — every sort key must exist on every document for keyset pagination',\n );\n }\n nextCursor = encodeCursor({ sort: config.sort, values });\n }\n return { data: page as unknown as DocOf2<X>[], nextCursor, hasMore };\n };\n\n return { paginateCursor };\n};\n","/**\n * Offset pagination strategy — `paginateFlexible`, via a **single `$facet`\n * aggregation round-trip**: `$match` + `$facet { data: [sort/skip/limit/post],\n * totalCount: [$count] }`. One network call returns both the page and the total\n * — the ORM's key pagination perf win vs the classic count-then-find pattern.\n */\nimport type { Abortable, AggregateOptions, Document } from 'mongodb';\nimport { DEFAULT_FIND_LIMIT, DEFAULT_MAX_LIMIT } from '../../shared/constants.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport { normalizePageLimit } from '../../shared/pagination-math.ts';\nimport { buildPaginationResult, type PaginationResult } from '../../shared/pagination-result.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport { checkDocsDrift } from '../drift.ts';\nimport { resolveDriftMode } from '../query-options.ts';\nimport type { PaginationConfig, PaginationCtx, PaginationDocOf } from './types.ts';\n\n/** Build the `paginateFlexible` closure from the shared pagination context. */\nexport const makePaginateFlexible = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: PaginationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = PaginationDocOf<TClients, TDb, X>;\n\n const { client, dbLabel, logger, opts, resolve, cachedAggregate } = ctx;\n\n const paginateFlexible = async <X extends C>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n config: PaginationConfig = {},\n ): Promise<PaginationResult<DocOf2<X>>> => {\n const normalized = normalizePageLimit(\n {\n ...(config.page !== undefined ? { page: config.page } : {}),\n ...(config.limit !== undefined ? { limit: config.limit } : {}),\n },\n config.maxLimit ?? DEFAULT_MAX_LIMIT,\n // Same default as `findMany`/`paginateCursor` — the two pagination\n // APIs used to disagree silently (10 vs 100).\n { limit: DEFAULT_FIND_LIMIT },\n );\n\n const dataStages: Document[] = [\n ...(config.prePipeline ?? []),\n ...(config.sort && Object.keys(config.sort).length > 0 ? [{ $sort: config.sort }] : []),\n { $skip: normalized.offset },\n { $limit: normalized.limit },\n ...(config.projection !== undefined ? [{ $project: config.projection }] : []),\n ...(config.postPipeline ?? []),\n ];\n\n const pipeline: Document[] = [\n { $match: baseFilter },\n {\n $facet: {\n data: dataStages,\n totalCount: [{ $count: 'count' }],\n },\n },\n ];\n\n return cachedAggregate<X, PaginationResult<DocOf2<X>>>({\n collection,\n opName: 'mongo.paginateFlexible',\n pipeline,\n ...(config.queryOptions !== undefined ? { options: config.queryOptions } : {}),\n execute: async (r) => {\n const aggOptions = {\n ...(r.driverOpts as Record<string, unknown>),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n ...(r.sdk.batchSize !== undefined ? { batchSize: r.sdk.batchSize } : {}),\n } as AggregateOptions & Abortable;\n const rows = await client\n .collection<Document>(resolve(String(collection)))\n .aggregate(pipeline, aggOptions)\n .toArray();\n const row = rows[0] as\n | { data?: DocOf2<X>[]; totalCount?: Array<{ count: number }> }\n | undefined;\n const data = row?.data ?? [];\n const totalCount = row?.totalCount?.[0]?.count ?? 0;\n // Projected (lean) pages intentionally lack the collection's full field\n // set, so the schema-drift check is meaningless for them — skip it.\n if (config.projection === undefined) {\n checkDocsDrift(\n {\n logger,\n db: dbLabel,\n drift: resolveDriftMode(config.queryOptions?.drift, opts.drift),\n ...(opts.getSchema !== undefined ? { getSchema: opts.getSchema } : {}),\n },\n String(collection),\n 'mongo.paginateFlexible',\n data as Document[],\n );\n }\n return buildPaginationResult(data, totalCount, normalized.page, normalized.limit);\n },\n });\n };\n\n return { paginateFlexible };\n};\n","/**\n * Pagination op factory — `makePaginationOps`. Composes the two pagination\n * strategies into one op set per database:\n *\n * - `./offset.ts` — `paginateFlexible` (single `$facet` round-trip, with totals)\n * - `./cursor.ts` — `paginateCursor` (keyset / cursor, O(log n) per page)\n *\n * Both share a small context (`./types.ts`) built here.\n */\nimport type { Db } from 'mongodb';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { createCachedAggregate } from '../aggregation/cached-read.ts';\nimport { makeOpDeps } from '../op-deps.ts';\nimport { makePaginateCursor } from './cursor.ts';\nimport { makePaginateFlexible } from './offset.ts';\nimport type { PaginationCtx, PaginationOpsOptions } from './types.ts';\n\n/**\n * Pagination ops for one database: `paginateFlexible` (offset, `$facet`) and\n * `paginateCursor` (keyset). Both are collection-name first and schema-typed.\n * `paginateFlexible` routes through the shared cached-aggregation runner\n * (write-through cache + dedup); `paginateCursor` is a find-based keyset read\n * and stays uncached (its opaque cursor pages are largely unique).\n */\nexport const makePaginationOps = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n client: Db,\n dbLabel: string,\n logger: LoggerLike,\n opts: PaginationOpsOptions,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n\n const resolve = opts.resolveCollectionName;\n const deps = makeOpDeps<C>(logger, dbLabel, resolve, opts.wrapMongoErrors === true);\n\n const ctx: PaginationCtx<TClients, TDb> = {\n client,\n dbLabel,\n logger,\n opts,\n resolve,\n deps,\n cachedAggregate: createCachedAggregate<C>({ client, deps, opts, resolve }),\n };\n\n return {\n ...makePaginateFlexible<TClients, TDb>(ctx),\n ...makePaginateCursor<TClients, TDb>(ctx),\n };\n};\n\n// Re-export the public pagination types so the folder barrel matches the old\n// single-module exports.\nexport type {\n CursorPage,\n CursorPaginationConfig,\n PaginationConfig,\n PaginationOpsOptions,\n} from './types.ts';\n","import type { CreateCollectionOptions, Db, Document } from 'mongodb';\nimport { type ObjectField, toMongoValidator } from '../schema/index.ts';\nimport type { IndexSpec } from '../types.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\n\nexport interface CollectionRegistryEntry {\n schema?: ObjectField;\n indexes?: IndexSpec[];\n}\n\n/** What `syncIndexes` changed on a collection. */\nexport interface SyncIndexesResult {\n /** Names of indexes that were created (missing declared indexes). */\n created: string[];\n /** Names of indexes that were dropped (undeclared, excluding `_id_`). */\n dropped: string[];\n}\n\n/**\n * Canonical key signature for comparing index definitions. Key ORDER is\n * significant server-side (a compound index's prefix determines which sorts\n * it supports), so `{ userId: 1, createdAt: -1 }` and\n * `{ createdAt: -1, userId: 1 }` are DIFFERENT indexes. Relevant options are\n * folded into the signature so a declared-unique index never silently matches\n * an existing non-unique one. Both sides pass through the same projection:\n * server-reported index documents carry extra fields (`v`, `ns`, …) that must\n * not leak into the comparison.\n */\ninterface IndexOptionLike {\n unique?: unknown;\n sparse?: unknown;\n expireAfterSeconds?: unknown;\n}\n\nconst optionSignature = (o?: IndexOptionLike): string =>\n JSON.stringify([\n Boolean(o?.unique),\n Boolean(o?.sparse),\n typeof o?.expireAfterSeconds === 'number' ? o.expireAfterSeconds : null,\n ]);\n\nconst indexKeyOf = (key: Document, options?: IndexOptionLike): string =>\n `${JSON.stringify(Object.keys(key).map((k) => [k, key[k]]))}|${optionSignature(options)}`;\n\nexport interface SchemaOpsOptions {\n resolveCollectionName: (logical: string) => string;\n getDefinition: (logical: string) => CollectionRegistryEntry | undefined;\n}\n\n/**\n * Schema-first collection management.\n *\n * `createSchema` is IDEMPOTENT and SELF-RECONCILING: on a NEW collection it\n * provisions the `$jsonSchema` validator derived from the ORM schema plus the\n * declared indexes; when the collection ALREADY exists it upgrades the DB\n * schema to match the current ORM schema — hot-swapping the validator via\n * `collMod` only when it has actually drifted, and creating any newly-declared\n * indexes. It never drops indexes or data (destructive reconciliation stays\n * explicit via `syncIndexes`), so it is safe to call on every boot: the Mongo\n * schema follows the app schema automatically as models change.\n *\n * `updateSchema` hot-swaps a validator explicitly (via `collMod`);\n * `syncIndexes` reconciles index drift (create missing, drop undeclared).\n */\nexport const makeSchemaOps = (client: Db, _logger: LoggerLike, opts: SchemaOpsOptions) => {\n /** Read the `$jsonSchema` validator currently installed on a physical collection. */\n const readCollectionValidator = async (physical: string): Promise<Document | undefined> => {\n const info = (await client.listCollections({ name: physical }).next()) as\n | { options?: { validator?: Document } }\n | undefined;\n return info?.options?.validator;\n };\n\n /**\n * Create any declared index that is missing from the live collection.\n * ADDITIVE ONLY — never drops an existing (possibly undeclared) index; that\n * stays the explicit job of `syncIndexes`.\n */\n const ensureDeclaredIndexes = async (\n collection: string,\n physical: string,\n def?: CollectionRegistryEntry,\n ): Promise<void> => {\n const declared = def?.indexes ?? [];\n if (declared.length === 0) return;\n const handle = client.collection(physical);\n const existing = new Set(\n (await handle.listIndexes().toArray())\n .filter((i) => i.name !== '_id_')\n .map((i) => indexKeyOf(i.key as Document, i as IndexOptionLike)),\n );\n for (const index of declared) {\n if (existing.has(indexKeyOf(index.key as Document, index.options))) continue;\n try {\n await handle.createIndex(index.key as Document, index.options);\n } catch (err) {\n if ((err as { code?: number })?.code === 85 /* IndexOptionsConflict */) {\n // An index with the same name/key exists but with different options\n // (e.g. `unique` added). Can't be applied additively — tell the user\n // how to reconcile instead of failing the whole boot.\n throw new Error(\n `Cannot apply declared index on \"${collection}\": an index with the same ` +\n `name/key already exists with different options. Run ` +\n `db.syncIndexes(\"${collection}\") to reconcile index drift.`,\n { cause: err },\n );\n }\n throw err;\n }\n }\n };\n\n /**\n * Provision a collection with its `$jsonSchema` validator + declared indexes,\n * or — when the collection already exists — reconcile it to the current\n * schema (validator hot-swap + missing declared indexes). Idempotent: safe to\n * call on every boot.\n */\n const createSchema = async (\n collection: string,\n createCollectionOptions?: CreateCollectionOptions,\n ): Promise<void> => {\n const physical = opts.resolveCollectionName(collection);\n const def = opts.getDefinition(collection);\n // Caller options FIRST, derived validator LAST — a stale `validator`\n // key in the options must not clobber the schema-derived one.\n const createOptions = {\n ...(createCollectionOptions ?? {}),\n ...(def?.schema ? { validator: toMongoValidator(def.schema) } : {}),\n } as CreateCollectionOptions;\n\n // Try the fast path first: create the collection (implicitly creating its\n // database). We intentionally skip a pre-flight `listCollections` — on a\n // not-yet-created database that errors with `NamespaceNotFound` (code 26).\n // Code 48 means a previous boot already provisioned the collection, in\n // which case we fall through to the reconcile path below.\n let created = true;\n try {\n await client.createCollection(physical, createOptions);\n } catch (err) {\n if ((err as { code?: number })?.code !== 48) throw err;\n created = false;\n }\n\n if (created) {\n try {\n await ensureDeclaredIndexes(collection, physical, def);\n } catch (err) {\n // Roll back so a half-provisioned collection (validator, no indexes)\n // isn't left behind on partial failure.\n await client.dropCollection(physical).catch(() => {});\n throw err;\n }\n return;\n }\n\n // Collection already exists → self-heal to the current app schema: swap the\n // validator only when it actually drifted, and create any missing declared\n // indexes (never dropping anything — that is `syncIndexes`'s job).\n if (createOptions.validator) {\n const current = await readCollectionValidator(physical);\n if (JSON.stringify(current) !== JSON.stringify(createOptions.validator)) {\n await client.command({ collMod: physical, validator: createOptions.validator });\n }\n }\n await ensureDeclaredIndexes(collection, physical, def);\n };\n\n /** Hot-swap a collection's validator via `collMod` (no downtime). */\n const updateSchema = async (collection: string, schema?: ObjectField): Promise<void> => {\n const physical = opts.resolveCollectionName(collection);\n const def = opts.getDefinition(collection);\n const resolved = schema ?? def?.schema;\n if (!resolved) {\n throw new Error(`No schema available for collection \"${collection}\"`);\n }\n await client.command({\n collMod: physical,\n validator: toMongoValidator(resolved),\n });\n };\n\n /**\n * Reconcile a collection's real indexes with the declared ones: create any\n * missing declared index and drop any undeclared one (`_id_` is always kept).\n * Matching compares key ORDER and the `unique`/`sparse`/`expireAfterSeconds`\n * options — an option-divergent same-key index is treated as missing (the\n * declared version is created; the divergent one is dropped as undeclared).\n * CAUTION: indexes on shared collections created by OTHER services are\n * treated as undeclared here — list them in the definition or don't share.\n * Expects the collection to already exist (`createSchema` first). Returns\n * the created/dropped index names.\n */\n const syncIndexes = async (collection: string): Promise<SyncIndexesResult> => {\n const physical = opts.resolveCollectionName(collection);\n const def = opts.getDefinition(collection);\n const declared = def?.indexes ?? [];\n const handle = client.collection(physical);\n const existing = (await handle.listIndexes().toArray()).filter((i) => i.name !== '_id_');\n const existingByKey = new Map(\n existing.map((i) => [indexKeyOf(i.key as Document, i as IndexOptionLike), i.name as string]),\n );\n const declaredByKey = new Map(\n declared.map((d) => [indexKeyOf(d.key as Document, d.options), d]),\n );\n const created: string[] = [];\n const dropped: string[] = [];\n for (const [key] of declaredByKey) {\n if (!existingByKey.has(key)) {\n await handle.createIndex(\n (declaredByKey.get(key) as IndexSpec).key as Document,\n (declaredByKey.get(key) as IndexSpec).options,\n );\n }\n }\n // Resolve the real names of the indexes we just created (auto-named when no\n // explicit `name` was given, e.g. `sku_1`) so the report is meaningful.\n const after = (await handle.listIndexes().toArray()).filter((i) => i.name !== '_id_');\n const afterByKey = new Map(\n after.map((i) => [indexKeyOf(i.key as Document, i as IndexOptionLike), i.name as string]),\n );\n for (const [key, spec] of declaredByKey) {\n if (!existingByKey.has(key)) {\n created.push(spec.options?.name ?? afterByKey.get(key) ?? JSON.stringify(spec.key));\n }\n }\n for (const [key, name] of existingByKey) {\n if (!declaredByKey.has(key)) {\n await handle.dropIndex(name);\n dropped.push(name);\n }\n }\n return { created, dropped };\n };\n\n return { createSchema, updateSchema, syncIndexes };\n};\n","import type { ClientSession, Db, MongoClient, TransactionOptions } from 'mongodb';\nimport { isTransactionUnsupportedError, mapMongoDriverError } from '../errors/index.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\n\nexport interface TransactionOpsOptions {\n migrationCollectionPhysical: string;\n /** Map driver errors to typed DomainError/InfraError before rethrowing. */\n wrapMongoErrors?: boolean;\n}\n\n/**\n * Transaction + idempotent-migration ops for one database handle.\n */\nexport const makeTransactionOps = (\n client: MongoClient,\n handle: Db,\n logger: LoggerLike,\n _config: Record<string, unknown>,\n opts: TransactionOpsOptions,\n) => {\n let warnedUnsupported = false;\n let journalIndexReady = false;\n\n /** Migration claim lease in ms — mirrors `MongoMigrationRunnerOptions.leaseMs` default. */\n const MIGRATE_LEASE_MS = 120_000;\n\n /**\n * Run `fn(session)` inside a transaction. On standalone servers where\n * transactions are unsupported (error code 20 / message sniff), falls back\n * to running `fn(null)`. The fallback warning fires once per handle — not\n * per call.\n */\n const transaction = async <T>(\n fn: (session: ClientSession | null) => Promise<T>,\n options?: TransactionOptions,\n ): Promise<T> => {\n const session = client.startSession();\n try {\n return await session.withTransaction(async () => fn(session), options);\n } catch (err) {\n // Standalone (and deployments without retryable writes) can't run\n // transactions; fall back to running `fn(null)` non-transactionally.\n if (isTransactionUnsupportedError(err)) {\n if (!warnedUnsupported) {\n warnedUnsupported = true;\n logger.warn?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'transactions unsupported on this deployment, falling back to non-transactional',\n );\n }\n return fn(null);\n }\n if (opts.wrapMongoErrors) {\n throw mapMongoDriverError(err, { db: handle.databaseName, op: 'transaction' });\n }\n throw err;\n } finally {\n await session.endSession();\n }\n };\n\n /**\n * Idempotent migration claim — lease-based, mirroring `migrations/journal.ts`:\n *\n * - A unique index on `name` (best-effort, created once per handle)\n * arbitrates concurrent fresh claims.\n * - An EXISTING row is only STOLEN when `status: 'running'` (or another\n * non-applied marker) AND its lease has EXPIRED (hard-crash recovery).\n * A LIVE claim held by another runner is never taken over — concurrent\n * `migrate(name)` calls can no longer execute `fn` twice.\n * - Legacy rows without `status` are treated as applied (never stolen).\n * - On failure the claim is deleted so the migration can be retried; if\n * the claim vanished mid-run, an `applied` row is restored instead of\n * silently allowing a future re-run.\n */\n const migrate = async (\n name: string,\n fn: (session: ClientSession | null) => Promise<void>,\n filePath?: string,\n ): Promise<void> => {\n const journal = handle.collection<{\n name: string;\n appliedAt: Date;\n status?: string;\n file?: string;\n expiresAt?: Date;\n }>(opts.migrationCollectionPhysical);\n\n // createIndex can't run inside a transaction — do it before claiming.\n // Best-effort: single-runner setups still work without uniqueness.\n if (!journalIndexReady) {\n try {\n await journal.createIndex({ name: 1 }, { unique: true });\n } catch {\n /* restricted permissions or conflicting index — claim still works single-runner */\n }\n journalIndexReady = true;\n }\n\n const isDupKeyError = (err: unknown): boolean => {\n const code = (err as { code?: number } | null)?.code;\n if (code === 11000 || code === 11001) return true;\n return /E11000 duplicate key/.test(String((err as Error | null)?.message ?? ''));\n };\n\n await transaction(async (session) => {\n const sessionOpts = session ? { session } : {};\n const now = new Date();\n const expiresAt = new Date(Date.now() + MIGRATE_LEASE_MS);\n\n // Step 1 — steal an EXPIRED non-applied claim (crashed runner). Live\n // leases and applied/status-less (legacy) rows never match.\n const stole = (await journal.findOneAndUpdate(\n {\n name,\n status: { $exists: true, $nin: ['applied'] },\n $or: [\n { expiresAt: { $lt: now } },\n {\n expiresAt: { $exists: false },\n appliedAt: { $lt: new Date(now.getTime() - MIGRATE_LEASE_MS) },\n },\n ],\n },\n {\n $set: {\n status: 'running',\n appliedAt: now,\n expiresAt,\n ...(filePath ? { file: filePath } : {}),\n },\n },\n { returnDocument: 'before', ...sessionOpts },\n )) as Document | null;\n if (stole !== null) {\n await runClaimed(session);\n return;\n }\n\n // Step 2 — fresh claim; the unique index decides concurrent inserts.\n try {\n await journal.insertOne(\n {\n name,\n appliedAt: now,\n status: 'running',\n expiresAt,\n ...(filePath ? { file: filePath } : {}),\n },\n sessionOpts,\n );\n } catch (err) {\n if (!isDupKeyError(err)) throw err;\n // Lost the race: applied (or legacy) → done; live claim → skip.\n const existing = (await journal.findOne(\n { name },\n { projection: { status: 1 }, ...sessionOpts },\n )) as Document | null;\n const status = existing?.status;\n if (status === undefined || status === 'applied') {\n logger.info({ name }, 'migration already applied, skipping');\n } else {\n logger.warn({ name }, 'migration claim held by another runner, skipping');\n }\n return;\n }\n await runClaimed(session);\n });\n\n async function runClaimed(session: ClientSession | null): Promise<void> {\n const sessionOpts = session ? { session } : {};\n // Heartbeat extends the lease while a long `fn` runs — only possible in\n // fallback (non-transactional) mode: inside a transaction the row is\n // invisible/locked to outside updates until commit.\n const heartbeat =\n session === null\n ? setInterval(() => {\n void journal\n .updateOne(\n { name, status: 'running' },\n { $set: { expiresAt: new Date(Date.now() + MIGRATE_LEASE_MS) } },\n )\n .catch(() => {});\n }, MIGRATE_LEASE_MS / 2)\n : undefined;\n heartbeat?.unref?.();\n try {\n await fn(session);\n const res = (await journal.updateOne(\n { name, status: 'running' },\n { $set: { status: 'applied' } },\n sessionOpts,\n )) as unknown as Document & { matchedCount?: number };\n // Zero matches = the running row vanished concurrently — restore an\n // applied row so the migration is never silently re-run later.\n if (res?.matchedCount === 0) {\n await journal\n .insertOne({ name, appliedAt: new Date(), status: 'applied' }, sessionOpts)\n .catch(() => {});\n }\n } catch (err) {\n await journal.deleteOne({ name }, sessionOpts).catch(() => {});\n throw err;\n } finally {\n if (heartbeat !== undefined) clearInterval(heartbeat);\n }\n }\n };\n\n return { transaction, migrate };\n};\n\ntype Document = Record<string, unknown>;\n","/**\n * Per-database manager assembly. `buildManager` is the composition point of the\n * op-factory pattern: it builds the collection registry (schema/hooks/\n * timestamps), resolves logical→physical names, and **spreads** every\n * `make*Ops` factory into one `CollectionManager` object per database.\n *\n * The `CollectionManager` type mirrors that spread as an intersection so both\n * the runtime value and its type stay in sync from a single source.\n */\nimport type { Db, Document, MongoClient } from 'mongodb';\nimport type { InFlight } from '../cache/in-flight.ts';\nimport type { QueryCache } from '../cache/query-cache.ts';\nimport { BadRequest } from '../errors/index.ts';\nimport type { HooksRegistry } from '../hooks/hooks.ts';\nimport { makePopulator, type PopulateOptions } from '../relation/populate.ts';\nimport type { JoinedFields, RelationDef, ValidRelation } from '../relation/relation.ts';\nimport type { DriftMode } from '../schema/validate-doc/index.ts';\nimport type { CollectionLike, DbClientsDefinition } from '../types.ts';\nimport { asCollectionDefinition, type ExtractDbNames } from '../types.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\nimport { makeAggregationOps } from './aggregation/index.ts';\nimport type { CacheInvalidationRef } from './cache-invalidation.ts';\nimport { createResolveCollectionName } from './collection-name.ts';\nimport type { CrudOps, TimestampsByCollection } from './crud/index.ts';\nimport { makeCrudOps } from './crud/index.ts';\nimport { makePaginationOps } from './pagination/index.ts';\nimport { makeSchemaOps } from './schema-ops.ts';\nimport { makeTransactionOps } from './transaction.ts';\n\n/** Everything `buildManager` needs from the composition root. */\nexport interface BuildManagerDeps<TClients extends DbClientsDefinition> {\n dbClients: TClients;\n config: { defaultDb: string; migrationDir: string; appName: string };\n logger: LoggerLike;\n sharedCache?: QueryCache;\n dedupeReads: boolean;\n inFlight: InFlight;\n wrapMongoErrors: boolean;\n drift?: DriftMode;\n /** Watch refs for cache-invalidation (physical names) — pushed to as managers build. */\n collectionRefs: CacheInvalidationRef[];\n /** The shared `db` record (sibling managers reference each other cross-DB). */\n db: Record<string, unknown>;\n}\n\n/** One collection manager per connected DB — the ORM's primary surface. */\nexport type CollectionManager<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> = CrudOps<TClients, TDb> &\n ReturnType<typeof makePaginationOps<TClients, TDb>> &\n ReturnType<typeof makeAggregationOps<TClients, TDb>> &\n ReturnType<typeof makeSchemaOps> &\n ReturnType<typeof makeTransactionOps> & {\n /**\n * DataLoader-backed relation population (kills N+1). Each relation is\n * validated against the schema registry (`collection` / `localField` /\n * `foreignField` / `through`), and the joined `as` fields are typed.\n */\n populate: <const T extends Document, const R extends readonly RelationDef[]>(\n docs: T[],\n relations: R & { [K in keyof R]: ValidRelation<TClients, TDb, T, R[K]> },\n options?: PopulateOptions,\n ) => Promise<Array<T & JoinedFields<TClients, TDb, R>>>;\n /** Raw `db()` handle escape hatch. */\n client: Db;\n /** Reference to sibling managers (cross-DB). */\n db: Record<string, unknown>;\n };\n\n/** Assemble one database's `CollectionManager` from the shared deps. */\nexport const buildManager = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n deps: BuildManagerDeps<TClients>,\n dbKey: TDb,\n dbName: string,\n client: MongoClient,\n): CollectionManager<TClients, TDb> => {\n const { dbClients, config, logger, sharedCache, dedupeReads, inFlight, collectionRefs } = deps;\n const definition = dbClients[dbKey]!;\n const handle = client.db(dbName);\n const baseResolveCollectionName = createResolveCollectionName(definition);\n\n // Normalize each collection: schema-or-definition → { schema, indexes, hooks }.\n const registry = new Map<string, ReturnType<typeof asCollectionDefinition>>();\n const hooks: HooksRegistry = {};\n const timestamps: TimestampsByCollection = {};\n for (const [logical, value] of Object.entries(definition.collections)) {\n const def = asCollectionDefinition(value as CollectionLike);\n registry.set(logical, def);\n hooks[logical] = def.hooks as HooksRegistry[string];\n if (def.timestamps) timestamps[logical] = def.timestamps;\n // Cache-invalidation watchers track the PHYSICAL name (that's what cache\n // keys use), so writes to the raw collection invalidate the right reads.\n collectionRefs.push({ db: handle, collection: baseResolveCollectionName(logical) });\n }\n const getDefinition = (logical: string) => registry.get(logical);\n\n // Fail fast with a clear message on unknown collection names. The type\n // system rejects them at compile time; this catches plain-JS callers\n // instead of surfacing an obscure driver error (or an empty result).\n // Internal `_`-prefixed collections (e.g. the `_migrations` journal) are\n // allowed through.\n const resolveCollectionName = (logical: string): string => {\n if (!registry.has(logical) && !logical.startsWith('_')) {\n throw new BadRequest(`Unknown collection \"${logical}\"`);\n }\n return baseResolveCollectionName(logical);\n };\n\n const crud = makeCrudOps<TClients, TDb>(handle, dbName, logger, {\n resolveCollectionName,\n wrapMongoErrors: deps.wrapMongoErrors,\n ...(sharedCache !== undefined ? { cache: sharedCache } : {}),\n dedupeReads,\n inFlight,\n hooks,\n timestamps,\n ...(deps.drift !== undefined ? { drift: deps.drift } : {}),\n ...(getDefinition !== undefined\n ? { getSchema: (logical: string) => getDefinition(logical)?.schema }\n : {}),\n });\n const pagination = makePaginationOps<TClients, TDb>(handle, dbName, logger, {\n resolveCollectionName,\n wrapMongoErrors: deps.wrapMongoErrors,\n ...(deps.drift !== undefined ? { drift: deps.drift } : {}),\n ...(getDefinition !== undefined\n ? { getSchema: (logical: string) => getDefinition(logical)?.schema }\n : {}),\n ...(sharedCache !== undefined ? { cache: sharedCache } : {}),\n dedupeReads,\n inFlight,\n });\n const aggregation = makeAggregationOps<TClients, TDb>(handle, dbName, logger, {\n resolveCollectionName,\n wrapMongoErrors: deps.wrapMongoErrors,\n ...(sharedCache !== undefined ? { cache: sharedCache } : {}),\n dedupeReads,\n inFlight,\n });\n const schema = makeSchemaOps(handle, logger, { resolveCollectionName, getDefinition });\n const transactionOps = makeTransactionOps(client, handle, logger, config, {\n migrationCollectionPhysical: resolveCollectionName('_migrations'),\n wrapMongoErrors: deps.wrapMongoErrors,\n });\n const populator = makePopulator({\n findMany: async (logical, filter, options) => {\n const physical = resolveCollectionName(logical);\n return handle\n .collection<Document>(physical)\n .find(filter, {\n ...(options?.projection !== undefined ? { projection: options.projection } : {}),\n limit: options?.limit ?? 10_000,\n })\n .toArray();\n },\n });\n const populate = (async <const T extends Document, const R extends readonly RelationDef[]>(\n docs: T[],\n relations: R & { [K in keyof R]: ValidRelation<TClients, TDb, T, R[K]> },\n options: PopulateOptions = {},\n ): Promise<Array<T & JoinedFields<TClients, TDb, R>>> => {\n const result = await populator.populate(docs, relations as unknown as RelationDef[], options);\n return result as Array<T & JoinedFields<TClients, TDb, R>>;\n }) as CollectionManager<TClients, TDb>['populate'];\n\n return {\n ...crud,\n ...pagination,\n ...aggregation,\n ...schema,\n ...transactionOps,\n populate,\n client: handle,\n db: deps.db,\n };\n};\n","/**\n * Service facade — the composition root. `createMongoService` wires the whole\n * ORM: it resolves config (`./config.ts`), opens pooled connections\n * (`./connection.ts`), assembles one `CollectionManager` per database\n * (`./manager.ts`), and exposes health (`./health.ts`).\n *\n * Kept deliberately thin: each concern lives in a sibling module and is only\n * composed here.\n */\nimport { type MongoClient, ObjectId } from 'mongodb';\nimport { InFlight } from '../cache/in-flight.ts';\nimport type { DbClientsDefinition, ExtractDbNames } from '../types.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\nimport type { CacheInvalidationRef } from './cache-invalidation.ts';\nimport { CacheInvalidator } from './cache-invalidation.ts';\nimport {\n type MongoServiceConfig,\n type ResolvedServiceConfig,\n resolveRuntimeConfig,\n} from './config.ts';\nimport {\n closeConnections as closePool,\n makeConnectionFactory,\n makeGetDbUrl,\n} from './connection.ts';\nimport { createHealth, type HealthReport } from './health.ts';\nimport { buildManager, type CollectionManager } from './manager.ts';\n\nexport type MongoService<TClients extends DbClientsDefinition = DbClientsDefinition> = {\n db: {\n [K in ExtractDbNames<TClients> as `${K}Client`]: CollectionManager<TClients, K>;\n };\n /** Open the pooled MongoClients and build all managers. */\n makeConnections: (names?: (keyof TClients & string)[]) => Promise<void>;\n closeConnections: () => Promise<void>;\n /** Run `fn` over every connected manager (in parallel). */\n eachDb: <T>(fn: (manager: unknown, dbKey: string) => Promise<T>) => Promise<T[]>;\n /** Ping every connected database and report per-DB health. */\n health: () => Promise<HealthReport>;\n getDbUrl: (name: string) => string;\n config: { defaultDb: string; migrationDir: string; appName: string };\n logger: LoggerLike;\n ObjectId: typeof ObjectId;\n};\n\n/**\n * Assemble the ORM service from a client definition:\n *\n * const service = createMongoService({\n * primary: {\n * name: 'app',\n * dbUrl: process.env.MONGO_URL,\n * collectionPrefix: process.env.DB_PREFIX,\n * collections: { users: userSchema, orders: { schema: orderSchema, indexes: [...] } },\n * },\n * });\n * await service.makeConnections();\n * const users = service.db.primaryClient;\n * await users.insertOne('users', { email });\n * const page = await users.paginateFlexible('users', {}, { page: 1, limit: 20 });\n */\nexport const createMongoService = <TClients extends DbClientsDefinition = DbClientsDefinition>(\n dbClients: TClients,\n configOverrides: MongoServiceConfig = {},\n): MongoService<TClients> => {\n const runtime: ResolvedServiceConfig = resolveRuntimeConfig(configOverrides);\n const { config, logger, sharedCache, dedupeReads } = runtime;\n\n const db: Record<string, unknown> = {};\n const openedClients = new Map<string, MongoClient>();\n const inFlight = new InFlight();\n const getDbUrl = makeGetDbUrl(dbClients, config);\n // Optional change-stream invalidation of the shared cache (external writers).\n const collectionRefs: CacheInvalidationRef[] = [];\n const cacheInvalidator =\n sharedCache !== undefined && configOverrides.cacheWatch === true\n ? new CacheInvalidator({ cache: sharedCache, logger })\n : undefined;\n\n const baseMakeConnections = makeConnectionFactory(\n dbClients,\n db,\n getDbUrl,\n ((key: string, dbName: string, client: MongoClient) =>\n buildManager(\n {\n dbClients,\n config,\n logger,\n ...(sharedCache !== undefined ? { sharedCache } : {}),\n dedupeReads,\n inFlight,\n wrapMongoErrors: runtime.wrapMongoErrors,\n ...(configOverrides.drift !== undefined ? { drift: configOverrides.drift } : {}),\n collectionRefs,\n db,\n },\n key as ExtractDbNames<TClients>,\n dbName,\n client,\n )) as (dbKey: string, dbName: string, client: MongoClient) => unknown,\n openedClients,\n );\n // Open change-stream cache-invalidation watchers once connections are up, and\n // tear them down before the pool closes.\n const makeConnections = async (names?: (keyof TClients & string)[]): Promise<void> => {\n await baseMakeConnections(names);\n await cacheInvalidator?.start(collectionRefs);\n };\n const closeConnections = async (): Promise<void> => {\n await cacheInvalidator?.stop();\n collectionRefs.length = 0;\n await closePool(openedClients);\n };\n\n const eachDb = async <T>(fn: (manager: unknown, dbKey: string) => Promise<T>): Promise<T[]> => {\n return Promise.all(Object.keys(db).map((key) => fn(db[key], key.replace(/Client$/, ''))));\n };\n\n const health = createHealth(db);\n\n return {\n db: db as MongoService<TClients>['db'],\n makeConnections,\n closeConnections,\n eachDb,\n health,\n getDbUrl,\n config,\n logger,\n ObjectId,\n };\n};\n\nexport type { CacheInvalidationRef } from './cache-invalidation.ts';\nexport { CacheInvalidator } from './cache-invalidation.ts';\nexport type { ResolvedServiceConfig } from './config.ts';\n// Re-export the public service surface so `service/index.ts` remains the single\n// import site (matches the pre-refactor exports; the barrel re-exports these).\nexport { type MongoServiceConfig, resolveCache } from './config.ts';\nexport { createHealth, type DbHealthResult, type HealthReport } from './health.ts';\nexport { type BuildManagerDeps, buildManager, type CollectionManager } from './manager.ts';\n","import type { Document, Filter } from 'mongodb';\n\nconst isOperatorDoc = (value: unknown): value is Document =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n\n/**\n * Merge multiple Mongo filters into one. Empty/undefined parts are skipped.\n *\n * Conflicting keys deep-merge when BOTH sides are plain objects (operator\n * documents like `{ $gte: 18 }` / `{ $in: [...] }`), so\n * `merge({ role: 'admin', age: { $gte: 18 } }, { age: { $lte: 65 } })`\n * keeps both range clauses instead of the old shallow-assign silently\n * dropping `$gte`. Scalars replace (last write wins). Top-level `$and`/`$or`\n * arrays CONCATENATE — dropping a sibling branch would change semantics.\n */\nexport const mergeMongoFilters = <T extends Document>(\n ...parts: Array<Filter<T> | undefined>\n): Filter<T> => {\n const out: Document = {};\n for (const part of parts) {\n if (!part) continue;\n for (const [key, value] of Object.entries(part as Document)) {\n if (!(key in out)) {\n out[key] = value;\n continue;\n }\n if (key === '$and' || key === '$or') {\n const prev = out[key];\n out[key] = [\n ...(Array.isArray(prev) ? prev : [prev]),\n ...(Array.isArray(value) ? value : [value]),\n ];\n continue;\n }\n const prev = out[key];\n out[key] = isOperatorDoc(prev) && isOperatorDoc(value) ? { ...prev, ...value } : value;\n }\n }\n return out as Filter<T>;\n};\n","/** Remove the `_id` field from a document (returns the same object when absent). */\nexport const stripDocumentId = <T extends Record<string, unknown>>(doc: T): Omit<T, '_id'> => {\n if (!('_id' in doc)) return doc;\n const { _id, ...rest } = doc;\n void _id;\n return rest;\n};\n\n/** Remove an arbitrary primary key field from an object. */\nexport const stripPrimaryKey = <T extends Record<string, unknown>, K extends keyof T & string>(\n patch: T,\n key: K,\n): Omit<T, K> => {\n if (!(key in patch)) return patch;\n const { [key]: _, ...rest } = patch;\n void _;\n return rest;\n};\n","import { createMongoMigrationRunner, type MongoMigrationRunner } from './migrations/index.ts';\nimport type { MongoService, MongoServiceConfig } from './service/index.ts';\nimport { createMongoService } from './service/index.ts';\nimport type { DbClientsDefinition } from './types.ts';\n\nexport interface MongoToolkitOptions extends MongoServiceConfig {}\n\n/**\n * Convenience bundle: service + migration runner sharing one config.\n *\n * const toolkit = createMongoToolkit({ primary: { name, collections } });\n * await toolkit.service.makeConnections();\n * await toolkit.migrations.up();\n */\nexport const createMongoToolkit = <TClients extends DbClientsDefinition = DbClientsDefinition>(\n dbClients: TClients,\n options: MongoToolkitOptions = {},\n): {\n service: MongoService<TClients>;\n migrations: MongoMigrationRunner;\n} => {\n const service = createMongoService(dbClients, options);\n const migrations = createMongoMigrationRunner(service, {\n migrationDir: service.config.migrationDir,\n });\n return { service, migrations };\n};\n\nexport type MongoToolkit<TClients extends DbClientsDefinition> = ReturnType<\n typeof createMongoToolkit<TClients>\n>;\n","/**\n * Generic keyed factory caches (memoization). Unlike the ORM's `QueryCache`\n * (per-collection, TTL, invalidation-aware) and `HotCache` (read-through,\n * event/timer-refreshed), these are dependency-free building blocks for\n * memoizing any expensive computation by key — including in-flight dedup so a\n * keyed factory never runs twice concurrently.\n */\nimport { LRU } from './lru.ts';\n\nexport interface CacheOptions {\n /** Max cached entries. `0` or negative → unbounded Map (default 100). */\n maxSize?: number;\n}\n\ntype BackingStore<K, V> = {\n get(k: K): V | undefined;\n set(k: K, v: V): void;\n has(k: K): boolean;\n delete(k: K): void;\n};\n\nconst makeStore = <K, V>(maxSize: number): BackingStore<K, V> => {\n if (maxSize <= 0) {\n const map = new Map<K, V>();\n return {\n get: (k) => map.get(k),\n set: (k, v) => {\n map.set(k, v);\n },\n has: (k) => map.has(k),\n delete: (k) => {\n map.delete(k);\n },\n };\n }\n return new LRU<K, V>({ max: maxSize });\n};\n\n/**\n * Synchronous keyed factory cache: one value per key, LRU-bounded.\n * Used for cheap singleton factories (connection pools, resolvers, ...).\n */\nexport const createCachedFactory = <K, V>(\n factory: (key: K) => V,\n options: CacheOptions = {},\n): ((key: K) => V) => {\n const maxSize = options.maxSize ?? 100;\n const cache = makeStore<K, V>(maxSize);\n return (key: K): V => {\n const existing = cache.get(key);\n if (existing !== undefined) return existing;\n const value = factory(key);\n cache.set(key, value);\n return value;\n };\n};\n\n/**\n * Async keyed factory cache with **in-flight deduplication**: concurrent calls\n * with the same key share a single Promise so the factory runs only once.\n * On settle (success or failure) the in-flight entry is removed.\n */\nexport const createCachedAsyncFactory = <K, V>(\n factory: (key: K) => Promise<V>,\n options: CacheOptions = {},\n): ((key: K) => Promise<V>) => {\n const maxSize = options.maxSize ?? 100;\n const cache = makeStore<K, Promise<V>>(maxSize);\n const inFlight = new Map<K, Promise<V>>();\n\n return (key: K): Promise<V> => {\n const inflight = inFlight.get(key);\n if (inflight) return inflight;\n\n const cached = cache.get(key);\n if (cached) return cached;\n\n const promise = factory(key);\n inFlight.set(key, promise);\n cache.set(key, promise);\n promise.then(\n () => {\n inFlight.delete(key);\n },\n () => {\n inFlight.delete(key);\n // Never cache a failure — evict (identity-guarded) so the next call\n // retries instead of re-surfacing the same rejected promise.\n if (cache.get(key) === promise) cache.delete(key);\n },\n );\n return promise;\n };\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/timeout.ts","../src/capabilities.ts","../src/utils/redact.ts","../src/errors/classes.ts","../src/errors/transient.ts","../src/errors/driver-map.ts","../src/errors/http-status.ts","../src/utils/clone.ts","../src/utils/hash.ts","../src/utils/lru.ts","../src/cache/in-flight.ts","../src/cache/hot-cache/size.ts","../src/cache/hot-cache/ticker.ts","../src/cache/hot-cache/types.ts","../src/utils/watch-errors.ts","../src/cache/hot-cache/watcher.ts","../src/cache/hot-cache/index.ts","../src/cache/query-cache.ts","../src/graceful-transaction.ts","../src/hooks/hooks.ts","../src/loader/dataloader.ts","../src/migrations/types.ts","../src/migrations/files.ts","../src/migrations/journal.ts","../src/migrations/index.ts","../src/mongo-helpers.ts","../src/shared/constants.ts","../src/query-builder/query-builder.ts","../src/relation/relation.ts","../src/repository/repository.ts","../src/schema/collections.ts","../src/schema/to-mongo-schema.ts","../src/schema/types.ts","../src/schema/validate-doc/helpers.ts","../src/schema/validate-doc/raw.ts","../src/schema/validate-doc/field-validators.ts","../src/schema/validate-doc/validate.ts","../src/service/collection-name.ts","../src/service/connection-uri.ts","../src/service/cache-invalidation.ts","../src/utils/logger.ts","../src/service/config.ts","../src/service/connection.ts","../src/service/health.ts","../src/relation/populate.ts","../src/types.ts","../src/service/trace-db-op.ts","../src/service/op-deps.ts","../src/service/query-options.ts","../src/service/crud-op.ts","../src/service/pipeline-builder.ts","../src/service/aggregation-stages.ts","../src/service/aggregation/aggregate.ts","../src/service/aggregation/helpers.ts","../src/service/aggregation/cached-read.ts","../src/service/aggregation/group.ts","../src/service/aggregation/lookup-join.ts","../src/shared/pagination-math.ts","../src/shared/pagination-result.ts","../src/service/aggregation-pipeline.ts","../src/service/aggregation/text-search.ts","../src/service/aggregation/index.ts","../src/schema/apply-defaults.ts","../src/utils/omit-undefined.ts","../src/service/drift.ts","../src/service/update-format.ts","../src/service/crud/context.ts","../src/shared/soft-delete.ts","../src/service/crud/read-ops.ts","../src/service/crud/watch-ops.ts","../src/service/crud/write-ops.ts","../src/service/crud/index.ts","../src/shared/keyset.ts","../src/service/pagination/cursor.ts","../src/service/pagination/offset.ts","../src/service/pagination/index.ts","../src/service/schema-ops.ts","../src/service/transaction.ts","../src/service/manager.ts","../src/service/index.ts","../src/shared/merge-filters.ts","../src/shared/strip-primary-key.ts","../src/toolkit.ts","../src/utils/memoize.ts"],"names":["ObjectId","sum","deps","canonicalKey","basename","join","options","out","isPlainObject","Decimal128","Long","BSON","SEP","buildManager","meta","s","mergeAggOptions","pipeline","opts","EJSON","randomUUID","closeConnections","prev"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Race a promise against a timeout. A `timeoutMs` <= 0 disables the timer and\n * returns the original promise untouched (zero-overhead fast path).\n */\nexport const withTimeout = <T>(\n promise: Promise<T>,\n timeoutMs: number,\n label: string,\n): Promise<T> => {\n if (timeoutMs <= 0) return promise;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(() => {\n reject(new Error(`Operation timed out after ${timeoutMs}ms: ${label}`));\n }, timeoutMs);\n });\n return Promise.race([promise, timeout]).finally(() => {\n if (timer !== undefined) clearTimeout(timer);\n });\n};\n\n/**\n * Sleep helper used by retry backoff.\n *\n * `unref` (default false) detaches the timer from the event loop, so a\n * background retry loop never keeps the process alive on its own (the\n * consumer's server/sockets do that). Watcher backoff passes `unref: true`;\n * awaited query retries keep the default so a pending call is never dropped.\n */\nexport const sleep = (ms: number, unref = false): Promise<void> =>\n new Promise((resolve) => {\n const timer = setTimeout(resolve, ms);\n if (unref) timer.unref?.();\n });\n\n/**\n * Sleep for `ms` plus random jitter (0..jitterMs, capped at `ms`) so retry\n * loops don't resynchronize into a thundering herd after a replica failover.\n * Accepts the same `unref` option as {@link sleep}.\n */\nexport const sleepJittered = (ms: number, jitterMs = 1000, unref = false): Promise<void> =>\n sleep(ms + Math.floor(Math.random() * Math.min(ms, jitterMs)), unref);\n","import type { Db, Document, MongoClient } from 'mongodb';\nimport { withTimeout } from './utils/timeout.ts';\n\n/**\n * Transaction capability detection. MongoDB transactions require a replica set\n * (or mongos). The ORM probes once and caches the result so the transaction\n * wrapper can fall back to plain (non-transactional) execution on standalone\n * servers.\n */\nexport interface MongoCapabilities {\n probed: boolean;\n transactionsSupported: boolean;\n}\n\nexport interface MongoCapabilitiesStore {\n get(): MongoCapabilities;\n set(capabilities: MongoCapabilities): void;\n reset(): void;\n}\n\nexport const createMongoCapabilitiesStore = (): MongoCapabilitiesStore => {\n let state: MongoCapabilities = { probed: false, transactionsSupported: false };\n return {\n get: () => state,\n set: (capabilities) => {\n state = capabilities;\n },\n reset: () => {\n state = { probed: false, transactionsSupported: false };\n },\n };\n};\n\n/** `MONGO_USE_TRANSACTIONS=1|true|yes` forces transactions on/off. */\nexport const readMongoTransactionsEnvOverride = (): boolean | undefined => {\n const raw = process.env.MONGO_USE_TRANSACTIONS;\n if (raw === undefined) return undefined;\n return ['1', 'true', 'yes'].includes(raw.toLowerCase());\n};\n\n/** Probe a connected client/db via `hello`. */\nexport const probeMongoCapabilities = async (\n client: MongoClient | Db | null | undefined,\n): Promise<MongoCapabilities> => {\n try {\n const db = client && 'startSession' in client ? (client as MongoClient).db() : (client as Db);\n if (!db) return { probed: false, transactionsSupported: false };\n const hello = await withTimeout(\n db.admin().command({ hello: 1 } as Document),\n 5_000,\n 'probeMongoCapabilities: hello',\n );\n const isReplicaSet = typeof hello.setName === 'string' && hello.setName.length > 0;\n const isMongos = hello.msg === 'isdbgrid';\n return { probed: true, transactionsSupported: isReplicaSet || isMongos };\n } catch {\n return { probed: false, transactionsSupported: false };\n }\n};\n\n/** Effective transaction support: env override → probed value → URL heuristic. */\nexport const mongoTransactionsEnabled = (\n store: MongoCapabilitiesStore,\n options: { urlHint?: string; envOverride?: boolean } = {},\n): boolean => {\n const env = options.envOverride ?? readMongoTransactionsEnvOverride();\n if (env !== undefined) return env;\n const state = store.get();\n if (state.probed) return state.transactionsSupported;\n // `mongodb+srv` seeds always resolve to a replica-set/mongos topology.\n if (options.urlHint) return /replicaSet=|mongodb\\+srv:|loadBalanced=true/i.test(options.urlHint);\n return false;\n};\n","/**\n * Log-safe text helpers — credential masking for anything quoted out of a\n * driver error.\n *\n * The ORM quotes driver messages in errors, and those routinely embed the\n * connection URL they failed on (`mongodb://user:pass@host`) or a secret pair\n * (`token=…`). Every string that can reach a log line or a client payload goes\n * through {@link redactText} so a password is never captured by a log scraper or\n * pasted into a bug report.\n */\n\n/** `scheme://user:secret@host` — the password is the masked part. */\nconst CONNECTION_CREDENTIALS = /([a-z][a-z0-9+.-]*:\\/\\/[^/\\s:@]*):[^/\\s@]*@/gi;\n\n/** `password=…` / `token=…` / `api-key=…` pairs (query strings, log fields). */\nconst SECRET_PAIR =\n /\\b(password|passwd|pwd|secret|token|api[-_]?key|access[-_]?key)=([^&\\s;,\"')]+)/gi;\n\n/** Mask the password of `scheme://user:secret@host` connection strings. */\nexport const maskCredentials = (value: string): string =>\n value.replace(CONNECTION_CREDENTIALS, '$1:***@');\n\n/** Mask `password=…` / `token=…` style secret pairs. */\nexport const maskSecretPairs = (value: string): string => value.replace(SECRET_PAIR, '$1=***');\n\n/**\n * Make a quoted string safe to log or serialize: mask credentials and secret\n * pairs, collapse to the first line and clip it.\n *\n * @param value - The raw text (a driver message, a connection string, …).\n * @param max - Maximum length (default 300).\n * @returns The redacted, single-line text.\n */\nexport const redactText = (value: string, max = 300): string => {\n const single = maskSecretPairs(maskCredentials(value))\n .split('\\n')\n .find((line) => line.trim().length > 0);\n const text = (single ?? '').trim();\n return text.length <= max ? text : `${text.slice(0, max - 1)}…`;\n};\n","/**\n * The ORM's error classes (`AppError` → `DomainError` / `InfraError` /\n * `BadRequest`), their type guards, and the `ERROR_HTTP_STATUS` table that sets\n * each error's `statusCode` at construction.\n *\n * A leaf module: nothing else in `src/errors/` imports this (so `driver-map.ts`\n * and `http-status.ts` can depend on it without cycles).\n */\nimport { maskCredentials } from '../utils/redact.ts';\nexport interface ErrorContext {\n db?: string;\n collection?: string;\n op?: string;\n}\n\n/**\n * Canonical HTTP status for each error code. `AppError.statusCode` is set from\n * this table at construction (falling back to the class default: 400 for\n * `DomainError`, 500 for `InfraError`), so a framework can respond with\n * `err.statusCode` directly and still get correct REST semantics:\n * NOT_FOUND → 404, DUPLICATE_KEY/VERSION_CONFLICT/COLLECTION_EXISTS → 409,\n * VALIDATION_FAILED → 422, MONGO_TIMEOUT → 504.\n */\nexport const ERROR_HTTP_STATUS: Record<string, number> = {\n BAD_REQUEST: 400,\n NOT_FOUND: 404,\n DUPLICATE_KEY: 409,\n VERSION_CONFLICT: 409,\n COLLECTION_EXISTS: 409,\n SCHEMA_DRIFT: 409,\n VALIDATION_FAILED: 422,\n MONGO_TIMEOUT: 504,\n};\n\n/**\n * Canonical reason phrase per status, used when a message is NOT client-visible.\n *\n * Written out rather than read from `Response.statusText` (which is empty unless\n * a server supplied one), so a masked 5xx still says something a caller can act\n * on: \"Service Unavailable\" instead of an empty string.\n */\nexport const STATUS_MESSAGES: Record<number, string> = {\n 400: 'Bad Request',\n 401: 'Unauthorized',\n 403: 'Forbidden',\n 404: 'Not Found',\n 409: 'Conflict',\n 422: 'Unprocessable Entity',\n 429: 'Too Many Requests',\n 500: 'Internal Server Error',\n 502: 'Bad Gateway',\n 503: 'Service Unavailable',\n 504: 'Gateway Timeout',\n};\n\n/** The generic message for a status (unknown 5xx → \"Internal Server Error\"). */\nexport const genericStatusMessage = (statusCode: number): string =>\n STATUS_MESSAGES[statusCode] ?? (statusCode >= 500 ? 'Internal Server Error' : 'Request failed');\n\nexport class AppError extends Error {\n readonly code: string;\n readonly statusCode: number;\n readonly extra?: Record<string, unknown>;\n /**\n * Whether `message`/`extra` may be sent to a CLIENT.\n *\n * Fail-closed: a 4xx message is the caller's contract, a 5xx message is an\n * operator detail that may quote a driver, a host or a query. Pass `expose`\n * explicitly to override — only for a 5xx whose text was written for callers\n * (e.g. `new InfraError(\"DRAINING\", \"queue is draining\", extra, true)`).\n */\n readonly expose: boolean;\n\n constructor(\n code: string,\n message: string,\n statusCode = 500,\n extra?: Record<string, unknown>,\n expose?: boolean,\n ) {\n super(message);\n this.name = 'AppError';\n this.code = code;\n this.statusCode = statusCode;\n this.expose = expose ?? statusCode < 500;\n if (extra !== undefined) this.extra = extra;\n }\n\n /**\n * Full, stack-free shape for LOGS and typed consumers:\n * `{ name, code, message, statusCode, ...(extra) }`.\n *\n * It carries the real message, so it is NOT the client path — use\n * {@link toClientPayload} (or `serializeError`) for anything a caller sees, and\n * prefer `logger.error({ err })` so pino's own serializer keeps the stack in the\n * log rather than in a payload.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n statusCode: this.statusCode,\n ...(this.extra !== undefined ? { extra: this.extra } : {}),\n };\n }\n\n /**\n * The client-safe payload — the same shape as {@link toJSON}, except that a\n * non-exposed error's `message` is replaced by the canonical reason phrase and\n * its `extra` is dropped. A framework can forward this (or `serializeError`'s\n * result) without auditing what the message might contain.\n *\n * @param options - `expose: true` forces the real (masked) message + extra.\n * @returns The client payload.\n */\n toClientPayload(options: { expose?: boolean } = {}): Record<string, unknown> {\n const expose = options.expose === true || this.expose;\n const payload: Record<string, unknown> = {\n name: this.name,\n code: this.code,\n message: expose ? maskCredentials(this.message) : genericStatusMessage(this.statusCode),\n statusCode: this.statusCode,\n };\n if (expose && this.extra !== undefined) payload.extra = this.extra;\n return payload;\n }\n}\n\nexport class DomainError extends AppError {\n constructor(code: string, message: string, extra?: Record<string, unknown>, expose?: boolean) {\n super(code, message, ERROR_HTTP_STATUS[code] ?? 400, extra, expose);\n this.name = 'DomainError';\n }\n}\n\nexport class InfraError extends AppError {\n constructor(code: string, message: string, extra?: Record<string, unknown>, expose?: boolean) {\n super(code, message, ERROR_HTTP_STATUS[code] ?? 500, extra, expose);\n this.name = 'InfraError';\n }\n}\n\nexport class BadRequest extends DomainError {\n constructor(message: string, extra?: Record<string, unknown>, expose?: boolean) {\n super('BAD_REQUEST', message, extra, expose);\n this.name = 'BadRequest';\n }\n}\n\nexport const isAppError = (err: unknown): err is AppError => err instanceof AppError;\n\nexport const isDomainError = (err: unknown): err is DomainError => err instanceof DomainError;\n\nexport const isInfraError = (err: unknown): err is InfraError => err instanceof InfraError;\n","/**\n * Transient-error detection: which MongoDB errors are safe to retry. This is a\n * leaf module (no folder imports) so both `driver-map.ts` and `http-status.ts`\n * can depend on it without cycles.\n */\n\n/**\n * Server error codes MongoDB raises that are safe to retry (network hiccups,\n * not-primary, sharding moves, interrupted queries). Mirrors the reference set.\n *\n * Frozen + typed `ReadonlySet` so a consumer can't mutate the shared instance\n * (it is a module-level singleton, re-exported through the barrel).\n */\nexport const TRANSIENT_MONGO_ERROR_CODES: ReadonlySet<number> = Object.freeze(\n new Set<number>([\n 6, // HostUnreachable\n 7, // HostNotFound\n 89, // NetworkTimeout\n 91, // ShutdownInProgress\n 189, // PrimarySteppedDown\n 251, // NoSuchTransaction (stepdown mid-transaction)\n 262, // ExceededTimeLimit (part of the retryable transaction set)\n 9001, // SocketException\n 10058, // NotWritablePrimary (legacy server code)\n 10107, // NotWritablePrimary\n 11600, // InterruptedAtShutdown\n 11602, // InterruptedDueToReplStateChange\n 13435, // NotPrimaryNoSecondaryOk\n 13436, // NotPrimaryOrSecondary\n ]),\n);\n\nconst TRANSIENT_NAME =\n /MongoNetworkError|PoolClearedError|MongoWriteConcernError|MongoNotPrimaryError|MongoNodeIsRecoveringError|MongoNetworkTimeoutError|MongoServerSelectionError/;\n\n/** True when the error is a transient Mongo failure that retry can recover from. */\nexport const isMongoTransientError = (error: unknown): boolean => {\n if (!error || typeof error !== 'object') return false;\n const e = error as {\n name?: unknown;\n code?: unknown;\n errInfo?: unknown;\n hasErrorLabel?: unknown;\n };\n if (\n typeof e.hasErrorLabel === 'function' &&\n (e.hasErrorLabel as (label: string) => boolean)('TransientTransactionError')\n ) {\n return true;\n }\n if (typeof e.name === 'string' && TRANSIENT_NAME.test(e.name)) return true;\n if (typeof e.code === 'number' && TRANSIENT_MONGO_ERROR_CODES.has(e.code)) return true;\n return false;\n};\n\n/** True when the error is a duplicate-key violation (code 11000 / E11000 message). */\nexport const isMongoDuplicateKeyError = (error: unknown): boolean => {\n if (!error || typeof error !== 'object') return false;\n const e = error as { code?: unknown; message?: unknown };\n if (e.code === 11000) return true;\n if (typeof e.message === 'string' && /E11000|duplicate key/i.test(e.message)) return true;\n return false;\n};\n\n/**\n * True when the deployment cannot run transactions at all (standalone mongod,\n * or storage engine without retryable writes) — callers fall back to\n * non-transactional execution. Shared by BOTH fallback layers\n * (`withGracefulMongoTransaction` and the service `transaction` op) so they\n * classify identically.\n */\nexport const isTransactionUnsupportedError = (error: unknown): boolean => {\n const code = (error as { code?: unknown } | null)?.code;\n // IllegalOperation or the already-mapped unsupported-transaction error.\n if (code === 20 || code === 'TRANSACTIONS_UNSUPPORTED') return true;\n const message = error instanceof Error ? error.message : '';\n return (\n /Transaction numbers are only allowed/i.test(message) ||\n /transactions are not supported/i.test(message) ||\n /does not support retryable writes/i.test(message)\n );\n};\n\nconst MONGO_ERROR_NAME =\n /MongoError|MongoServerError|MongoBulkWriteError|MongoNetworkError|MongoNetworkTimeoutError|MongoWriteConcernError|MongoNotPrimaryError|MongoNodeIsRecoveringError|MongoCursorExhaustedError|PoolClearedError|MongoTopologyClosedError|MongoServerSelectionError/;\n\n/**\n * Server codes that identify an error as coming from MongoDB even when the\n * `name` is absent — writeErrors[] entries, rethrown callbacks, and plain\n * objects users pass to `mapMongoDriverError` carry only `{ code }`.\n */\nconst DRIVER_ERROR_CODES: ReadonlySet<number> = Object.freeze(\n new Set<number>([\n 20, // IllegalOperation (transactions unsupported)\n 26, // NamespaceNotFound\n 48, // NamespaceExists\n 50, // MaxTimeMSExpired\n 112, // WriteConflict\n 121, // DocumentValidationFailure\n 11000, // DuplicateKey\n 11001, // DuplicateKey (legacy)\n ...TRANSIENT_MONGO_ERROR_CODES,\n ]),\n);\n\n/**\n * True when the error is a MongoDB DRIVER error rather than an application\n * error thrown inside a callback/transaction.\n *\n * Name-based (not instanceof) on purpose: the driver instance that raised the\n * error and the one this module imports may be different copies of the\n * `mongodb` package. A known numeric server code or duplicate-key message\n * also qualifies, so nameless-but-coded shapes (`{ code: 11000 }`) are still\n * recognized; application errors with arbitrary numeric codes are not.\n */\nexport const isMongoDriverError = (error: unknown): boolean => {\n if (!error || typeof error !== 'object') return false;\n const e = error as { name?: unknown; code?: unknown; message?: unknown };\n if (typeof e.name === 'string' && MONGO_ERROR_NAME.test(e.name)) return true;\n if (typeof e.code === 'number' && DRIVER_ERROR_CODES.has(e.code)) return true;\n if (typeof e.message === 'string' && /E11000 duplicate key/i.test(e.message)) return true;\n return false;\n};\n","/**\n * Raw driver-error mapping: turn Mongo driver errors (codes 11000, 112, 50,\n * 121, bulk-write, transient) into the ORM's typed `DomainError` / `InfraError`,\n * plus `extractValidationPaths` for surfacing which `$jsonSchema` fields failed.\n */\nimport { AppError, DomainError, type ErrorContext, InfraError } from './classes.ts';\nimport {\n isMongoDriverError,\n isMongoDuplicateKeyError,\n isMongoTransientError,\n} from './transient.ts';\n\n/** Shape of a single `writeErrors[]` entry on a `MongoBulkWriteError`. */\ninterface WriteErrorLike {\n code?: number;\n errmsg?: string;\n keyPattern?: Record<string, unknown>;\n keyValue?: Record<string, unknown>;\n errInfo?: unknown;\n}\n\n/** Shape of the `errInfo` MongoDB attaches to a `$jsonSchema` validation failure (code 121). */\ninterface MongoErrInfo {\n failingDocumentId?: unknown;\n details?: {\n schemaRulesNotSatisfied?: Array<{\n propertyName?: string;\n propertiesNotSatisfied?: Array<{ propertyName?: string }>;\n /** Unknown-key violations are reported as a list here (not propertiesNotSatisfied). */\n additionalProperties?: string[];\n }>;\n };\n}\n\n/**\n * Flatten the offending field paths from a `$jsonSchema` validation error so a\n * `VALIDATION_FAILED` error can name exactly which fields were rejected.\n * Covers missing/type-mismatched properties (`propertiesNotSatisfied`) and\n * unknown-key violations (`additionalProperties`).\n */\nexport const extractValidationPaths = (errInfo: unknown): string[] => {\n if (!errInfo || typeof errInfo !== 'object') return [];\n const info = errInfo as MongoErrInfo;\n const out: string[] = [];\n for (const rule of info.details?.schemaRulesNotSatisfied ?? []) {\n if (typeof rule.propertyName === 'string') out.push(rule.propertyName);\n for (const prop of rule.propertiesNotSatisfied ?? []) {\n if (typeof prop.propertyName === 'string') out.push(prop.propertyName);\n }\n for (const prop of rule.additionalProperties ?? []) {\n if (typeof prop === 'string') out.push(prop);\n }\n }\n return [...new Set(out)];\n};\n\n/** Enrich a mapped-error context with the failing document id + offending field paths. */\nconst addValidationContext = (context: Record<string, unknown>, errInfo: unknown): void => {\n if (!errInfo || typeof errInfo !== 'object') return;\n const info = errInfo as MongoErrInfo;\n if (info.failingDocumentId !== undefined) context.documentId = info.failingDocumentId;\n const fields = extractValidationPaths(errInfo);\n if (fields.length > 0) context.fields = fields;\n if (info.details !== undefined) context.details = info.details;\n};\n\nconst isBulkWriteError = (error: unknown): boolean =>\n typeof error === 'object' &&\n error !== null &&\n 'writeErrors' in (error as { writeErrors?: unknown }) &&\n Array.isArray((error as { writeErrors?: unknown[] }).writeErrors);\n\n/**\n * Map a raw driver error to a typed DomainError/InfraError. Mirrors the sdk-db\n * mapping table (codes 11000 → DUPLICATE_KEY, 112 → VERSION_CONFLICT,\n * 50 → MONGO_TIMEOUT, 121 → VALIDATION_FAILED, everything else → MONGO_QUERY_ERROR).\n * When the error is already an AppError it is returned unchanged.\n */\nexport const mapMongoDriverError = (error: unknown, ctx: ErrorContext = {}): unknown => {\n if (error instanceof AppError) return error;\n // Application errors (e.g. a 409 ConflictError thrown inside a transaction\n // callback or a route) are NOT driver errors — passing them through keeps\n // their status/message intact. Only actual driver errors get mapped.\n if (!isMongoDriverError(error)) return error;\n\n const context: Record<string, unknown> = { ...(ctx as Record<string, unknown>) };\n if (isMongoDuplicateKeyError(error)) {\n const e = error as { keyPattern?: Record<string, unknown>; keyValue?: Record<string, unknown> };\n if (e.keyPattern) context.keyPattern = e.keyPattern;\n if (e.keyValue) context.keyValue = e.keyValue;\n return new DomainError('DUPLICATE_KEY', 'Duplicate key error', context);\n }\n\n if (isBulkWriteError(error)) {\n const first = (error as { writeErrors: WriteErrorLike[] }).writeErrors[0];\n if (first?.code === 11000) {\n if (first.keyPattern) context.keyPattern = first.keyPattern;\n if (first.keyValue) context.keyValue = first.keyValue;\n // Fixed message: the raw `errmsg` embeds stored values\n // (`E11000 ... dup key: { email: \"victim@x.com\" }`) and this message is\n // forwarded to clients via `toJSON()`/`serializeError()`.\n return new DomainError('DUPLICATE_KEY', 'Duplicate key error', context);\n }\n if (first?.code === 121) {\n addValidationContext(context, first.errInfo);\n return new DomainError('VALIDATION_FAILED', 'Document failed schema validation', context);\n }\n return new InfraError('MONGO_QUERY_ERROR', 'Bulk write failed', context);\n }\n\n const code = (error as { code?: unknown }).code;\n switch (code) {\n case 20:\n return new InfraError(\n 'TRANSACTIONS_UNSUPPORTED',\n 'MongoDB deployment does not support transactions; enable allowNonTransactionalFallback to run non-atomically',\n context,\n );\n case 112:\n return new DomainError('VERSION_CONFLICT', 'Document version conflict', context);\n case 50:\n return new InfraError('MONGO_TIMEOUT', 'MongoDB operation timed out', context);\n case 121: {\n addValidationContext(context, (error as { errInfo?: unknown }).errInfo);\n return new DomainError('VALIDATION_FAILED', 'Document failed schema validation', context);\n }\n default:\n break;\n }\n\n if (isMongoTransientError(error)) {\n const e = error as { message?: string };\n return new InfraError('MONGO_QUERY_ERROR', e.message ?? 'Transient MongoDB error', context);\n }\n\n const msg = (error as { message?: string }).message ?? 'MongoDB query error';\n return new InfraError('MONGO_QUERY_ERROR', msg, context);\n};\n\n/** True when the error is already a mapped AppError (used by callers that opted into wrapping). */\nexport const isMappedMongoError = (error: unknown): error is AppError => error instanceof AppError;\n","/**\n * Framework-facing error helpers: `httpStatusForError` (effective HTTP status\n * for any thrown value) and `serializeError` (reduce any thrown value to a\n * stable, client-safe payload).\n */\n\nimport { redactText } from '../utils/redact.ts';\nimport { AppError, type ErrorContext, genericStatusMessage } from './classes.ts';\nimport { mapMongoDriverError } from './driver-map.ts';\nimport { isMongoTransientError } from './transient.ts';\n\n/** Effective HTTP status for any thrown value: AppError-aware, raw → 500 (503 transient). */\nexport const httpStatusForError = (err: unknown): number => {\n if (err instanceof AppError) return err.statusCode;\n if (isMongoTransientError(err)) return 503;\n return 500;\n};\n\n/** Options for {@link serializeError}. */\nexport interface SerializeErrorOptions {\n /**\n * Include the real message (and `extra`) even for a non-exposed error — the\n * development / trusted-caller path. It is still credential-masked.\n */\n expose?: boolean;\n}\n\n/**\n * Reduce any thrown value to a stable, CLIENT-SAFE error payload:\n * `{ name, code, message, statusCode, ...(extra) }`.\n *\n * Raw driver errors are mapped through `mapMongoDriverError` first, so a\n * framework can forward the result directly without parsing Mongo server\n * internals (`errInfo`, `writeErrors`, `keyPattern`, ...):\n *\n * app.use((err, _req, res, _next) => {\n * const payload = serializeError(err, { db, collection, op });\n * res.status(payload.statusCode).json(payload);\n * });\n *\n * Fail-closed by default: a 4xx message/extra is the caller's contract, while a\n * 5xx message is replaced by the canonical reason phrase (`Internal Server\n * Error`, `Service Unavailable`, …) and `extra` is dropped — a driver message\n * that quotes a host, a query or a stored value never reaches a client. The\n * detail stays on the error itself for logs; pass `{ expose: true }` (or a\n * per-error `expose`) to opt out for a trusted caller.\n */\nexport const serializeError = (\n err: unknown,\n ctx: ErrorContext = {},\n options: SerializeErrorOptions = {},\n): Record<string, unknown> => {\n const mapped = mapMongoDriverError(err, ctx);\n if (mapped instanceof AppError) return mapped.toClientPayload(options);\n\n const statusCode = httpStatusForError(mapped);\n const name = mapped instanceof Error ? mapped.name : 'UnknownError';\n if (options.expose !== true) {\n return { name, code: 'UNKNOWN', message: genericStatusMessage(statusCode), statusCode };\n }\n return {\n name,\n code: 'UNKNOWN',\n message: redactText(mapped instanceof Error ? mapped.message : String(mapped)),\n statusCode,\n };\n};\n","import {\n Binary,\n Code,\n DBRef,\n Decimal128,\n Double,\n Int32,\n Long,\n MaxKey,\n MinKey,\n ObjectId,\n Timestamp,\n} from 'mongodb';\n\n/**\n * Deep-clone a value while preserving the types `JSON.parse(JSON.stringify())`\n * would corrupt or flatten: `Date`, `ObjectId`, `RegExp`, the numeric/binary\n * BSON wrappers (`Decimal128`, `Long`, `Int32`, `Double`, `Timestamp`,\n * `Binary`, `MinKey`, `MaxKey`, `Code`, `DBRef`), and the JS containers\n * `Map` / `Set` / `Buffer` / typed arrays — without this, cached money fields\n * (`Decimal128`) or int64 values (`Long`) would clone into `{}`, and a\n * `Map` (no enumerable own properties) or `Buffer` would silently lose both\n * type and data in the generic-object fallback. Arrays and plain objects are\n * copied recursively; primitives pass through.\n * Used by the optional `clone` mode on `QueryCache` / `HotCache` so a caller\n * can't mutate a cached result and poison the shared cache.\n */\nexport const cloneDeep = <T>(value: T): T => {\n if (value instanceof Date) return new Date(value.getTime()) as T;\n if (value instanceof ObjectId) return new ObjectId(value.toHexString()) as T;\n if (value instanceof Decimal128) return Decimal128.fromString(value.toString()) as T;\n if (value instanceof Long) return Long.fromString(value.toString()) as T;\n if (value instanceof Int32) return new Int32(value.valueOf()) as T;\n if (value instanceof Double) return new Double(value.valueOf()) as T;\n // fromBits round-trips exactly; fromNumber loses low bits above 2^53.\n if (value instanceof Timestamp)\n return Timestamp.fromBits(value.getLowBits(), value.getHighBits()) as T;\n if (value instanceof Binary) {\n const bytes = Buffer.from(value.buffer);\n return new Binary(bytes, value.sub_type) as T;\n }\n if (value instanceof MinKey) return new MinKey() as T;\n if (value instanceof MaxKey) return new MaxKey() as T;\n if (value instanceof DBRef) {\n return new DBRef(value.collection, cloneDeep(value.oid), value.db) as T;\n }\n if (value instanceof Code) {\n return new Code(\n value.code,\n value.scope !== undefined ? cloneDeep(value.scope) : undefined,\n ) as T;\n }\n if (value instanceof RegExp) return new RegExp(value.source, value.flags) as T;\n if (value instanceof Map) {\n const out = new Map<unknown, unknown>();\n for (const [k, v] of value) out.set(cloneDeep(k), cloneDeep(v));\n return out as T;\n }\n if (value instanceof Set) {\n const out = new Set<unknown>();\n for (const v of value) out.add(cloneDeep(v));\n return out as T;\n }\n // Buffer first (a Uint8Array subclass); then any other typed array view.\n if (Buffer.isBuffer(value)) return Buffer.from(value) as T;\n if (ArrayBuffer.isView(value)) {\n const view = value as unknown as ArrayBufferView & { slice?: () => unknown };\n if (view instanceof DataView) {\n const bytes = view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);\n return new DataView(bytes) as T;\n }\n return typeof view.slice === 'function' ? (view.slice() as T) : value;\n }\n if (Array.isArray(value)) return value.map((item) => cloneDeep(item)) as T;\n if (value !== null && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = cloneDeep(v);\n }\n return out as T;\n }\n return value;\n};\n","import { createHash } from 'node:crypto';\nimport { BSON } from 'mongodb';\n\nconst { EJSON } = BSON;\n\ntype Canonical = null | string | number | boolean | Canonical[] | { [key: string]: Canonical };\n\nconst bsonTypeOf = (value: object): string | undefined => {\n const type = (value as { _bsontype?: unknown })._bsontype;\n return typeof type === 'string' ? type : undefined;\n};\n\nconst isPlainObject = (value: unknown): value is Record<string, unknown> => {\n if (value === null || typeof value !== 'object') return false;\n const prototype = Object.getPrototypeOf(value) as object | null;\n return (prototype === Object.prototype || prototype === null) && bsonTypeOf(value) === undefined;\n};\n\n/**\n * Canonical, type-preserving serialization. Every value carries a type tag so\n * user objects/strings cannot impersonate Date, ObjectId, RegExp, undefined, or\n * other special values. BSON wrappers are encoded through the driver's EJSON\n * implementation, including values from a second copy of the driver.\n */\nexport const stableStringify = (value: unknown): string => {\n const ancestors = new WeakSet<object>();\n const visit = (input: unknown): Canonical => {\n if (input === null) return { t: 'null' };\n if (input === undefined) return { t: 'undefined' };\n switch (typeof input) {\n case 'string':\n case 'boolean':\n return { t: typeof input, v: input };\n case 'number':\n if (Number.isNaN(input)) return { t: 'number', v: 'NaN' };\n if (input === Infinity) return { t: 'number', v: 'Infinity' };\n if (input === -Infinity) return { t: 'number', v: '-Infinity' };\n if (Object.is(input, -0)) return { t: 'number', v: '-0' };\n return { t: 'number', v: input };\n case 'bigint':\n return { t: 'bigint', v: input.toString() };\n case 'symbol':\n case 'function':\n throw new TypeError(`stableStringify: unsupported ${typeof input} value`);\n default:\n break;\n }\n\n const object = input as object;\n if (ancestors.has(object)) throw new TypeError('stableStringify: cyclic value');\n ancestors.add(object);\n try {\n if (input instanceof Date) {\n return { t: 'date', v: Number.isNaN(input.getTime()) ? 'Invalid' : input.toISOString() };\n }\n if (input instanceof RegExp) return { t: 'regexp', v: `re:${input.source}/${input.flags}` };\n const bsonType = bsonTypeOf(object);\n if (bsonType !== undefined) {\n return { t: 'bson', kind: bsonType, v: EJSON.stringify(input, { relaxed: false }) };\n }\n if (Array.isArray(input)) return { t: 'array', v: input.map(visit) };\n if (input instanceof Map) {\n return {\n t: 'map',\n v: [...input.entries()].map(([key, entry]) => [visit(key), visit(entry)]),\n };\n }\n if (input instanceof Set) return { t: 'set', v: [...input].map(visit) };\n if (Buffer.isBuffer(input)) return { t: 'buffer', v: input.toString('base64') };\n if (ArrayBuffer.isView(input)) {\n return {\n t: 'bytes',\n kind: input.constructor.name,\n v: Buffer.from(input.buffer, input.byteOffset, input.byteLength).toString('base64'),\n };\n }\n if (input instanceof ArrayBuffer) {\n return { t: 'arraybuffer', v: Buffer.from(input).toString('base64') };\n }\n if (isPlainObject(input)) {\n const out: Record<string, Canonical> = {};\n for (const key of Object.keys(input).sort()) out[key] = visit(input[key]);\n return { t: 'object', v: out };\n }\n throw new TypeError(`stableStringify: unsupported object ${input.constructor.name}`);\n } finally {\n ancestors.delete(object);\n }\n };\n return JSON.stringify(visit(value));\n};\n\n/** SHA-256 digest of the canonical input, safe to use as a complete cache key. */\nexport const hashString = (input: string): string =>\n createHash('sha256').update(input, 'utf8').digest('base64url');\n\nexport const stableHash = (value: unknown): string => hashString(stableStringify(value));\n","/**\n * Minimal dependency-free LRU cache backed by a Map (recency = insertion order).\n * get() re-inserts the entry so the most-recently-used item is always last.\n */\nexport interface LRUOptions {\n /** Maximum number of entries before the least-recently-used item is evicted. Must be > 0. */\n max: number;\n /**\n * Called when an entry is evicted by capacity pressure (NOT on explicit\n * delete/clear). Lets owners release side structures keyed by the entry.\n */\n onEvict?: (key: never, value: never) => void;\n}\n\nexport class LRU<K, V> {\n readonly max: number;\n private map = new Map<K, V>();\n private onEvict: ((key: K, value: V) => void) | undefined;\n /** Number of entries evicted to make room for new ones (capacity evictions only). */\n evictions = 0;\n\n constructor(options: LRUOptions) {\n if (options.max <= 0) throw new Error('LRU max must be > 0');\n this.max = options.max;\n // Contravariance-safe: `(key: never) => void` accepts any handler shape.\n this.onEvict = options.onEvict as ((key: K, value: V) => void) | undefined;\n }\n\n get size(): number {\n return this.map.size;\n }\n\n get(key: K): V | undefined {\n const value = this.map.get(key);\n if (value === undefined) return undefined;\n // Refresh recency.\n this.map.delete(key);\n this.map.set(key, value);\n return value;\n }\n\n peek(key: K): V | undefined {\n return this.map.get(key);\n }\n\n has(key: K): boolean {\n return this.map.has(key);\n }\n\n set(key: K, value: V): this {\n if (this.map.has(key)) this.map.delete(key);\n this.map.set(key, value);\n if (this.map.size > this.max) {\n const next = this.map.keys().next();\n if (next.done !== true) {\n const evictedKey = next.value;\n const evictedValue = this.map.get(evictedKey) as V;\n this.map.delete(evictedKey);\n this.evictions++;\n try {\n // Eviction hooks must never break the cache write path.\n this.onEvict?.(evictedKey, evictedValue);\n } catch {\n /* ignore */\n }\n }\n }\n return this;\n }\n\n delete(key: K): boolean {\n return this.map.delete(key);\n }\n\n clear(): void {\n this.map.clear();\n }\n\n keys(): IterableIterator<K> {\n return this.map.keys();\n }\n\n entries(): IterableIterator<[K, V]> {\n return this.map.entries();\n }\n\n [Symbol.iterator](): IterableIterator<[K, V]> {\n return this.map.entries();\n }\n}\n","/**\n * In-flight request coalescing: identical concurrent operations share a single\n * Promise so the underlying (expensive) work runs once. This is the \"query\n * dedup\" optimization used by the CRUD read path.\n */\nexport class InFlight {\n private pending = new Map<string, Promise<unknown>>();\n\n get size(): number {\n return this.pending.size;\n }\n\n run<T>(key: string, fn: () => Promise<T>): Promise<T> {\n const existing = this.pending.get(key);\n if (existing) return existing as Promise<T>;\n let promise: Promise<T>;\n try {\n // Call fn() SYNCHRONOUSLY (instead of Promise.resolve().then(fn)) so\n // the caller chain — route handler → ORM → hot-cache get/fetch — stays\n // on the stack for the ignex debugbar's span-origin capture. A detached\n // .then() microtask unwinds that chain, so origins truncate at this\n // wrapper and never reach the application code that issued the query.\n // Promise.resolve() still normalizes sync returns; the try/catch keeps\n // the old contract of turning a synchronous throw into a rejection.\n promise = Promise.resolve(fn());\n } catch (err) {\n promise = Promise.reject(err) as Promise<T>;\n }\n // Cleanup as a DETACHED side-chain: wrapping the returned promise in\n // .finally() would make Bun truncate the async chain at this wrapper and\n // hide the route handler from span origins again. Both handlers consume\n // the settlement so a rejected loader never surfaces as an unhandled\n // rejection.\n promise.then(\n () => {\n this.pending.delete(key);\n },\n () => {\n this.pending.delete(key);\n },\n );\n this.pending.set(key, promise);\n return promise;\n }\n\n clear(): void {\n this.pending.clear();\n }\n}\n","/**\n * Cheap, BSON-aware byte estimator used by the HotCache `maxValueBytes` guard.\n * It is deliberately approximate (strings 2 bytes/char, fixed sizes for\n * primitives/BSON kinds) — enough to reject pathologically large values without\n * the cost of a real BSON encoder.\n *\n * Coverage notes: `Map`/`Set`/typed arrays are measured (a loader returning a\n * big Map used to measure 0 bytes and bypass the guard entirely), and a\n * `seen` WeakSet makes cyclic structures safe (they report their traversed\n * size instead of crashing with a stack overflow inside `fetch`).\n */\nimport { ObjectId } from 'mongodb';\n\nconst OVERHEAD_PER_KEY = 8;\n\n/** Approximate in-memory byte size of a cached value (used to bound single entries). */\nexport const estimateSize = (value: unknown, seen?: WeakSet<object>): number => {\n if (value === null || value === undefined) return 0;\n if (typeof value === 'string') return value.length * 2;\n if (typeof value === 'number' || typeof value === 'boolean') return 8;\n if (typeof value === 'bigint') return 16;\n if (typeof value !== 'object') return 0;\n if (value instanceof ObjectId) return 16;\n if (value instanceof Date) return 8;\n\n const visit = (v: unknown): number => {\n // Cycle guard: revisit only counts the reference overhead once.\n if (v !== null && typeof v === 'object') {\n if (!seen) seen = new WeakSet();\n else if (seen.has(v as object)) return OVERHEAD_PER_KEY;\n seen.add(v as object);\n }\n return estimateSize(v, seen);\n };\n\n if (Array.isArray(value)) {\n let sum = OVERHEAD_PER_KEY * Math.max(value.length, 1);\n for (const v of value) sum += visit(v);\n return sum;\n }\n if (value instanceof Map) {\n let sum = OVERHEAD_PER_KEY * value.size;\n for (const [k, v] of value) sum += estimateSize(k, seen) + visit(v);\n return sum;\n }\n if (value instanceof Set) {\n let sum = OVERHEAD_PER_KEY * value.size;\n for (const v of value) sum += visit(v);\n return sum;\n }\n if (ArrayBuffer.isView(value)) {\n // Buffers/typed arrays: measure REAL bytes — iterating them as index-keyed\n // objects inflated the estimate ~10× and caused spurious sizeSkips.\n return (value as ArrayBufferView).byteLength + OVERHEAD_PER_KEY;\n }\n let sum = 0;\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n sum += k.length * 2 + OVERHEAD_PER_KEY + visit(v);\n }\n return sum;\n};\n","/**\n * Standalone-mode background refresh: a single global `setInterval` ticker that\n * re-runs the loaders of due entries and swaps the fresh values in. Stale values\n * keep being served until the swap (bounded staleness, reads never block).\n *\n * A strategy object owned by `HotCache` (see `./index.ts`); the host supplies\n * the registered queries, the fetch pipeline, and the logger via `TickerHost`.\n */\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport type { RegisteredQuery } from './types.ts';\n\nexport interface TickerHost {\n /** All registered queries (the ticker mutates their counters/refresh timestamps). */\n queries: () => Map<string, RegisteredQuery>;\n /** The shared read-through fetch pipeline (with in-flight dedup + gen guard). */\n fetch: (\n q: RegisteredQuery,\n key: string,\n args: readonly unknown[],\n gen: number,\n ) => Promise<unknown>;\n logger: LoggerLike;\n}\n\n/** Max loader kicks a single tick may launch (stampede guard after downtime). */\nconst MAX_TICK_INFLIGHT = 64;\n\n/** Global standalone refresh ticker. Owns the timer; stops cleanly via `stop()`. */\nexport class RefreshTicker {\n private timer: ReturnType<typeof setInterval> | undefined;\n private intervalMs: number;\n\n constructor(\n private host: TickerHost,\n tickIntervalMs: number,\n ) {\n this.intervalMs = tickIntervalMs;\n }\n\n /** Whether the timer is currently running. */\n get running(): boolean {\n return this.timer !== undefined;\n }\n\n /** Start the interval (idempotent). The timer is `.unref()`'d so it never holds the process open. */\n start(): void {\n if (this.timer) return;\n this.timer = setInterval(() => {\n try {\n this.tick();\n } catch (err) {\n this.host.logger.warn?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'hot cache tick failed',\n );\n }\n }, this.intervalMs);\n // Don't keep the process alive on a lone timer (serverless/CLI friendly).\n const t = this.timer as { unref?: () => unknown } | undefined;\n t?.unref?.();\n }\n\n /** Stop the interval (idempotent). */\n stop(): void {\n if (this.timer) {\n clearInterval(this.timer);\n this.timer = undefined;\n }\n }\n\n /**\n * Background refresh pass: re-run loaders for due entries, swap fresh values.\n * A per-tick in-flight budget bounds the stampede after downtime/throttling —\n * one sweep can't launch unbounded simultaneous loaders across all queries;\n * skipped entries stay due and are picked up by the next tick.\n */\n private tick(): void {\n const now = Date.now();\n let budget = MAX_TICK_INFLIGHT;\n for (const q of this.host.queries().values()) {\n if (q.refreshIntervalMs <= 0) continue;\n for (const [key, entry] of [...q.lru.entries()]) {\n if (entry.nextRefreshAt <= now) {\n if (budget <= 0) return;\n budget--;\n // Claim the slot BEFORE kicking so duplicate ticks joining the same\n // in-flight load don't inflate the refreshes counter; on failure the\n // catch resets `nextRefreshAt` (to `now`, not tick-start time).\n entry.nextRefreshAt = now + q.refreshIntervalMs;\n q.refreshes++;\n void this.host.fetch(q, key, entry.args, q.gen).catch((err) => {\n const current = q.lru.peek(key);\n if (current) current.nextRefreshAt = Date.now();\n this.host.logger.warn?.(\n {\n error: err instanceof Error ? err.message : String(err),\n query: q.name,\n },\n 'hot cache background refresh failed (stale value retained)',\n );\n });\n }\n }\n }\n }\n\n /**\n * In standalone mode the ticker only refreshes queries with an explicit\n * `refreshIntervalMs`. A query with neither `refreshIntervalMs` nor `ttlMs`\n * set is served until it is manually invalidated — an easy way to serve\n * unbounded-stale data. Surface those queries once so the operator opts in\n * deliberately.\n */\n warnUnboundedStaleness(): void {\n const unbounded = [...this.host.queries().values()].filter(\n (q) => q.refreshIntervalMs <= 0 && q.ttlMs <= 0,\n );\n if (unbounded.length === 0) return;\n this.host.logger.warn?.(\n { queries: unbounded.map((q) => q.name) },\n 'hot cache: standalone mode — these queries have no refreshIntervalMs/ttlMs, so values are served until manually invalidated (unbounded staleness); set refreshIntervalMs or ttlMs to bound it',\n );\n }\n}\n","/**\n * Types + constants for the HotCache layer. All type-only (plus the stream-key\n * separator constant), so the coordinating class (`HotCache` in `./index.ts`)\n * and its strategy modules (`./ticker.ts`, `./watcher.ts`) share one vocabulary\n * without importing each other's runtime logic.\n */\nimport type { Db } from 'mongodb';\nimport { stableStringify } from '../../utils/hash.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport type { LRU } from '../../utils/lru.ts';\n\n/** Separator used in stream/dedupe keys so names can't collide across parts. */\nexport const WATCH_SEP = '\\u0000';\n\n/** A collection to watch for invalidation. `collection` is the PHYSICAL name. */\nexport interface HotCollectionRef {\n /**\n * Raw `Db` handle (e.g. `service.db.primaryClient.client`) — or a lazy\n * `() => Db` accessor resolved when the watcher starts. The lazy form lets\n * apps register queries at module scope (before the connection exists) and\n * only touch the live handle at `start()` time.\n */\n db: Db | (() => Db);\n /** Physical collection name whose writes invalidate bound queries. */\n collection: string;\n /**\n * Fine-tuned invalidation: extract the document ids (or groups of ids) that\n * one loader call's arguments depend on. Without this, ANY write to the\n * collection purges every entry of every query bound to it; with it, a\n * change-stream event (replica mode) or a manual\n * `invalidateIds(collection, [id])` call purges ONLY the entries that\n * extracted this id — sibling entries stay warm.\n *\n * Return every id the result depends on (one per document, or many for\n * grouped/aggregated results). Ids may be strings, numbers, ObjectIds… —\n * they are compared after stable normalization, so an ObjectId and its hex\n * string match.\n *\n * Must be pure and cheap (it runs once per load). If it throws or returns a\n * non-array the entry is marked conservative: it is dropped by ANY targeted\n * change on that collection instead of being kept incorrectly.\n *\n * Typed as `never`-params (contravariance-safe, same trick as `LRU`'s\n * `onEvict`): declare your own parameter types and they line up with the\n * query's loader args — `idsOf: (team: string) => members(team)`.\n */\n idsOf?: (...args: never) => readonly unknown[];\n}\n\n/** Resolve a possibly-lazy collection ref to its live `Db` handle. */\nexport const resolveWatchDb = (ref: HotCollectionRef): Db =>\n typeof ref.db === 'function' ? (ref.db as () => Db)() : ref.db;\n\n/**\n * Normalize a watched document id into a comparable key so an id passed to\n * `invalidateIds` matches the same id extracted by `idsOf` regardless of\n * representation: an ObjectId and its 24-char hex string collapse to the same\n * key, numbers/bigints to their decimal form, Dates to an epoch marker.\n * Anything else falls back to a stable serialization. Over-matching is safe by\n * design — worst case one extra entry is purged.\n */\nexport const normalizeWatchId = (id: unknown): string => {\n if (typeof id === 'string') return id;\n if (typeof id === 'number' || typeof id === 'bigint') return String(id);\n if (id instanceof Date) return `d${id.getTime()}`;\n const hex =\n typeof id === 'object' && id !== null\n ? (id as { toHexString?: () => string }).toHexString\n : undefined;\n if (typeof hex === 'function') return hex.call(id); // ObjectId → hex string\n return stableStringify(id);\n};\n\n/** Opt-in query registration. `TArgs` = the parameter tuple, `TResult` = loader result. */\nexport interface HotQueryConfig<TArgs extends readonly unknown[], TResult> {\n /** Read-through loader executed on cache miss / background refresh. */\n loader: (...args: TArgs) => Promise<TResult>;\n /**\n * Optional cache-key extractor. Lets callers decide which parameters form the\n * key (e.g. hash only some of them). Default: `stableHash` of all arguments.\n */\n keyOf?: (...args: TArgs) => string;\n /** Per-query TTL in ms (`0` = no expiry). Defaults to `defaultTtlMs`. */\n ttlMs?: number;\n /** Per-query LRU cap. Defaults to `defaultMaxSize`. */\n maxSize?: number;\n /**\n * Background refresh interval in ms (standalone ticker only). Default `0` =\n * no background refresh — entries then update only via `ttlMs` expiry or\n * manual `invalidate*` calls. In standalone mode with `autoRefresh` on, a\n * query with neither `refreshIntervalMs` nor `ttlMs` set serves values until\n * it is manually invalidated (unbounded staleness); `start()` logs a warning\n * naming those queries so you can opt in deliberately.\n */\n refreshIntervalMs?: number;\n /**\n * Collections whose data changes invalidate this query. Used by replica mode\n * to open change-stream watchers. In standalone mode these have no effect\n * (the ticker refreshes instead) — use `invalidateCollection` manually if\n * needed.\n */\n watch?: HotCollectionRef[];\n /**\n * Clone results on every read so callers can't mutate the shared cached entry\n * (default false — cloning has a per-read cost; treat cached results as\n * read-only when disabled).\n */\n clone?: boolean;\n /**\n * Upper bound (bytes) for a cached value, estimated via a cheap BSON-aware\n * size probe. Larger values are still returned to the caller but are NOT\n * cached (a first oversized result logs a warning). Protects the LRU from\n * holding unbounded single entries. Default: no limit.\n */\n maxValueBytes?: number;\n}\n\nexport interface HotCacheOptions {\n /**\n * Replica-support probe. Default: `probeMongoCapabilities` over the first\n * watched collection's `db`. Return `true` → change-stream mode,\n * `false` → standalone ticker mode. A probe that returns no result (timeout)\n * falls back to standalone with a warning — pass `mode` to pin the behavior.\n */\n probe?: () => Promise<boolean>;\n /**\n * Pin the cache mode directly, skipping the probe entirely. `'replica'` opens\n * change-stream watchers, `'standalone'` starts the ticker. Useful when the\n * deployment is known (e.g. from connection config) and you want to avoid a\n * `hello` round-trip or a mis-detection.\n */\n mode?: 'replica' | 'standalone';\n /** Default per-query TTL in ms (`0` = no expiry). Default `0`. */\n defaultTtlMs?: number;\n /** Default per-query LRU cap. Default `500`. */\n defaultMaxSize?: number;\n /** Global ticker interval in ms (standalone mode). Default `1000`. */\n tickIntervalMs?: number;\n /**\n * Master switch for the standalone background-refresh ticker. `true` (default)\n * runs the global ticker that re-fetches entries at `refreshIntervalMs`. Set\n * `false` to turn off auto-refetch entirely — data then updates only via\n * manual `invalidate`/`invalidateParams`/`invalidateCollection` or `ttlMs`\n * expiry. Replica-mode change streams are event-driven and unaffected.\n */\n autoRefresh?: boolean;\n logger?: LoggerLike;\n}\n\nexport type HotCacheMode = 'unknown' | 'replica' | 'standalone';\n\n/** Typed handle returned by `register` — type-safe alternative to dynamic `get`. */\nexport interface HotQueryAccessor<TArgs extends readonly unknown[], TResult> {\n /** Read-through: serve from LRU, else run the loader. */\n get: (...args: TArgs) => Promise<TResult>;\n /**\n * Manual invalidation (fully typed, with intellisense on the parameters).\n * Called with no arguments it drops every cached entry for this query; called\n * with the query's parameters it drops only that parameter's entry.\n *\n * topProducts.invalidate(); // drop all\n * topProducts.invalidate(10); // drop only the { limit: 10 } entry\n */\n invalidate: {\n (): void;\n (...args: TArgs): void;\n };\n}\n\n/** One cached value + the bookkeeping that drives expiry / background refresh. */\nexport interface Entry {\n value: unknown;\n args: readonly unknown[];\n expiresAt: number;\n nextRefreshAt: number;\n /**\n * Namespaced watched-document dependencies (`${collection}${WATCH_SEP}${id}`)\n * extracted via each watch ref's `idsOf` at store time — what id-targeted\n * invalidation matches against. Empty = the extractor listed no ids for this\n * call, so targeted changes keep the entry (TTL/ticker/manual still apply).\n */\n deps?: readonly string[];\n /**\n * Conservative marker set when dependency extraction threw or returned a\n * non-array: the entry is dropped by ANY targeted change on its watched\n * collections (never kept incorrectly).\n */\n depsAll?: boolean;\n}\n\n/** Runtime state for one registered query (owned by `HotCache`, mutated by ticker/watcher). */\nexport interface RegisteredQuery {\n name: string;\n config: HotQueryConfig<readonly unknown[], unknown>;\n lru: LRU<string, Entry>;\n ttlMs: number;\n refreshIntervalMs: number;\n clone: boolean;\n maxValueBytes?: number;\n /** Precomputed at register time: any watch ref declares an `idsOf` extractor. */\n hasIdWatch: boolean;\n /** Bumped on every invalidation/clear so in-flight loads don't re-store stale data. */\n gen: number;\n hits: number;\n misses: number;\n refreshes: number;\n loadErrors: number;\n sizeSkips: number;\n /** Entries dropped by id-targeted invalidation (`invalidateIds` / change events). */\n idDrops: number;\n warnedSize: boolean;\n}\n\n/** Per-query runtime counters (see `HotCache.stats()`). */\nexport interface HotQueryStats {\n /** Current number of cached entries for this query. */\n size: number;\n /** Reads served from the LRU without running the loader. */\n hits: number;\n /** Reads that ran the loader (LRU miss or expired entry). */\n misses: number;\n /** Background refreshes kicked by the standalone ticker. */\n refreshes: number;\n /** Loader rejections (failed reads/refreshes). */\n loadErrors: number;\n /** Values too large to cache (`maxValueBytes`). */\n sizeSkips: number;\n /** Entries dropped by id-targeted invalidation (`invalidateIds` / change events). */\n idDrops: number;\n /** Capacity evictions (LRU). */\n evictions: number;\n}\n\n/** Snapshot of the whole cache (see `HotCache.stats()`). */\nexport interface HotCacheStats {\n mode: HotCacheMode;\n /** Number of registered queries. */\n queries: number;\n /** Total cached entries across all queries. */\n entries: number;\n perQuery: Record<string, HotQueryStats>;\n}\n","/**\n * Permanent change-stream error classification, shared by every `$changeStream`\n * watcher (service `CacheInvalidator` + hot-cache `WatchCoordinator`).\n *\n * These errors can NEVER be fixed by retrying — retrying only logs the same\n * warning every 1–5s forever and (with an un-unref'd timer) keeps the process\n * alive, which is wrong for a background watcher whose host server or build\n * should own the process lifetime. Watchers must classify them once, log once,\n * and stop (disable the watcher / fall back to the standalone ticker).\n *\n * Detection alone is not enough for the operator reading the log, though: \"change\n * streams unavailable permanently\" says nothing about *why* or *what to change*.\n * {@link explainPermanentWatchError} returns the cause-specific headline and the\n * one-line fix, so the warning that disables a watcher tells you it was the\n * credentials (fix the URL and restart) or a standalone server (use a replica\n * set or turn `cacheWatch` off).\n *\n * Deliberately NARROW on purpose: replica errors that ARE transient — e.g.\n * \"change stream history lost\" (resume-token expiry, collection dropped),\n * network drops, failovers — must stay in the retry path, where\n * invalidate-on-reopen restores correctness. Broad patterns (like `not\n * supported` or `ChangeStream`) are rejected here because they can misfire on\n * those recoverable errors.\n */\n\n/** Why a change stream can never succeed. */\nexport type PermanentWatchReason = 'standalone' | 'credentials';\n\n/** A cause-specific explanation of a permanent change-stream failure. */\nexport interface PermanentWatchExplanation {\n /** The classified reason. */\n readonly reason: PermanentWatchReason;\n /** Short headline for a log line (`change streams need a replica set`). */\n readonly headline: string;\n /** The fix, in one line. */\n readonly hint: string;\n}\n\n/** Standalone server: `$changeStream` is not supported at all. */\nconst STANDALONE = /only supported on replica sets|not supported on (?:a )?standalone/i;\n\n/**\n * Credentials/authorization problems: the user cannot run `aggregate` on this\n * collection/server. Wrong creds, missing roles, or a user created without the\n * `read`/`changeStream` privilege will never start working by retrying.\n */\nconst CREDENTIALS =\n /requires authentication|not authorized|unauthorized|authentication failed|Command .* requires authentication/i;\n\n/**\n * Explain a permanent change-stream failure, or return `undefined` when the\n * error is retryable (the caller must keep retrying with backoff in that case).\n *\n * @param message - The driver's error message.\n * @returns The reason + headline + fix, or `undefined` when retrying may work.\n */\nexport const explainPermanentWatchError = (\n message: string,\n): PermanentWatchExplanation | undefined => {\n if (STANDALONE.test(message)) {\n return {\n reason: 'standalone',\n headline: 'change streams need a replica set',\n hint:\n 'Point the connection at a replica set (a single-node replica set is fine for local dev), ' +\n 'or set cacheWatch: false / cache: { ttlMs } to run write-through only.',\n };\n }\n if (CREDENTIALS.test(message)) {\n return {\n reason: 'credentials',\n headline: 'the connection is not authorized for change streams',\n hint:\n 'Change streams need an authenticated user with the read + changeStream privilege ' +\n '(usually granted on the authSource database) — fix the credentials in .env, then restart.',\n };\n }\n return undefined;\n};\n\n/**\n * True when retrying this change-stream error can never succeed.\n *\n * @param message - The driver's error message.\n * @returns `true` for a definitive standalone/authorization verdict.\n */\nexport const isPermanentWatchError = (message: string): boolean =>\n explainPermanentWatchError(message) !== undefined;\n","/**\n * Replica-mode change-stream watchers: one long-lived `$changeStream` consumer\n * per (database, collection); every data change invalidates the queries bound\n * to that collection (event-driven, works across processes and external\n * writers). Document events are routed through `invalidateDocument` so queries\n * with an `idsOf` extractor purge only the entries depending on that document;\n * stream-wide events (drop/rename/invalidate) and reconnects invalidate the\n * whole collection.\n *\n * A strategy object owned by `HotCache` (see `./index.ts`). The host supplies\n * the registered queries, per-collection invalidation, and the mode-fallback\n * callback. On permanent \"not supported\" errors the watcher drops the stream\n * and, when every planned stream has failed, tells the host to flip to the\n * standalone ticker. Transient errors retry with jittered backoff.\n *\n * ## Failure semantics (the staleness window)\n *\n * `watchLoop` is the self-healing consumer. Any stream error or server-side\n * kill (network drop, replica failover, cursor invalidation) is logged, the\n * abandoned stream is closed, and the loop reconnects after a jittered backoff\n * (1s → 5s). On every REOPEN (`backoff > 0`) the bound collection is\n * invalidated **once**, dropping cached entries so anything written during the\n * outage is re-fetched on the next read — this \"invalidate-on-reopen\" is what\n * restores correctness after:\n *\n * - **Resume-token expiry** — a `ChangeStreamHistoryLost`/invalid-token error.\n * It is a recoverable error, NOT \"not supported\", so it stays in the retry\n * path. The re-opened stream has no resume token and starts from \"now\"; the\n * invalidate-on-reopen drops entries that could be stale.\n * - **Rollback / `invalidate` events** — a dropped or renamed collection emits\n * an `invalidate` event that ends the stream; the loop reconnects and\n * invalidates on reopen.\n * - **Consumer downtime** — while the consumer is down, writes are NOT\n * observed, so the in-process LRU keeps serving stale values (the inherent\n * tradeoff: low latency can hide stale reads). Staleness is bounded only by\n * reconnect latency + the invalidate-on-reopen, plus any per-query\n * `ttlMs`/`refreshIntervalMs`. A consumer that never reconnects leaves\n * entries stale forever unless TTL/refresh are set.\n */\nimport type { ChangeStream, Db } from 'mongodb';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { sleepJittered } from '../../utils/timeout.ts';\nimport {\n explainPermanentWatchError,\n isPermanentWatchError,\n type PermanentWatchExplanation,\n} from '../../utils/watch-errors.ts';\nimport { type HotCollectionRef, type RegisteredQuery, resolveWatchDb, WATCH_SEP } from './types.ts';\n\nexport interface WatchHost {\n /** All registered queries (their `watch` refs drive which streams to open). */\n queries: () => Map<string, RegisteredQuery>;\n /** Invalidate every query bound to a physical collection. */\n invalidateCollection: (collection: string) => void;\n /**\n * Invalidate only the entries that depend on one changed document (the\n * change event's `documentKey._id`). The host decides per query whether it\n * can target by id (`idsOf`) or must fall back to a coarse purge.\n */\n invalidateDocument: (collection: string, id: unknown) => void;\n /** Whether the cache is currently in replica mode (used before a fallback). */\n isReplica: () => boolean;\n /** Flip the cache to standalone mode + start the ticker (called after a total fallback). */\n fallbackToStandalone: () => void;\n logger: LoggerLike;\n}\n\n/**\n * Resolve a lazy `db` accessor defensively: module-scope registrations commonly\n * access connections that don't exist yet, so a THROW means \"not available\n * yet\" — never let it escape into an unhandled rejection.\n */\nconst resolveDbSafe = (ref: HotCollectionRef, logger: LoggerLike): Db | null => {\n try {\n return resolveWatchDb(ref);\n } catch (err) {\n logger.debug?.(\n { error: err instanceof Error ? err.message : String(err), collection: ref.collection },\n 'hot cache: watch db accessor not ready yet',\n );\n return null;\n }\n};\n\n/**\n * The `_id` of the document a change event touched, or `undefined` for\n * stream-wide events (drop / dropDatabase / rename / invalidate) that carry no\n * `documentKey` and must invalidate the whole collection. Real `_id` values are\n * never undefined — but they CAN be falsy (`0`, `''`), hence the explicit\n * null-check on the wrapper object instead of the id itself.\n */\nconst documentKeyOf = (change: unknown): unknown => {\n const key = (change as { documentKey?: { _id?: unknown } | null } | null | undefined)\n ?.documentKey;\n return key ? key._id : undefined;\n};\n\n/** Long-lived change-stream coordinator for replica mode. */\nexport class WatchCoordinator {\n private streams = new Map<string, ChangeStream>();\n private failedStreams = new Set<string>();\n private stopped = true;\n /** Guards against stacking reconnect timers when several accessors lag. */\n private reopenTimer: ReturnType<typeof setTimeout> | undefined;\n\n constructor(private host: WatchHost) {}\n\n /** Number of currently open change streams. */\n get size(): number {\n return this.streams.size;\n }\n\n /** Mark the coordinator as running and open watchers for all watch refs (idempotent). */\n start(): void {\n this.stopped = false;\n this.openWatchStreams();\n }\n\n /** Close every watcher and clear failure bookkeeping (idempotent). */\n async stop(): Promise<void> {\n this.stopped = true;\n if (this.reopenTimer) clearTimeout(this.reopenTimer);\n const closes = [...this.streams.values()].map((stream) => {\n try {\n return Promise.resolve(stream.close()).catch(() => {});\n } catch {\n return Promise.resolve();\n }\n });\n this.streams.clear();\n this.failedStreams.clear();\n await Promise.allSettled(closes);\n }\n\n private openWatchStreams(): void {\n const seen = new Set<string>();\n let deferred = false;\n for (const q of this.host.queries().values()) {\n for (const ref of q.config.watch ?? []) {\n const db = resolveDbSafe(ref, this.host.logger);\n // Accessor not ready yet (module-scope registration before connect):\n // retry the whole sweep shortly instead of losing the stream forever.\n if (!db) {\n deferred = true;\n continue;\n }\n const key = `${db.databaseName}${WATCH_SEP}${ref.collection}`;\n if (seen.has(key) || this.streams.has(key)) continue;\n seen.add(key);\n // The loop must NEVER float as an unhandled rejection — any escape\n // from its catch handler would crash the process (Node ≥ 15).\n void this.watchLoop(key, ref).catch((err) => {\n this.host.logger.error?.(\n { error: err instanceof Error ? err.message : String(err), collection: ref.collection },\n 'hot cache: watcher crashed',\n );\n });\n }\n }\n if (deferred && !this.stopped && !this.reopenTimer) {\n this.reopenTimer = setTimeout(() => {\n this.reopenTimer = undefined;\n if (!this.stopped) this.openWatchStreams();\n }, 5_000);\n this.reopenTimer.unref?.();\n }\n }\n\n /**\n * Long-lived change-stream consumer for one collection. Each data change\n * invalidates the queries bound to it. On permanent \"not supported\" errors the\n * watcher is dropped and, if every planned stream failed, the cache falls back\n * to the standalone ticker. Transient errors (including resume-token expiry,\n * rollbacks, and `invalidate` events) retry with backoff and invalidate the\n * collection on reopen so entries missed during the outage are re-fetched —\n * see the module doc for the full failure-semantics contract.\n */\n private async watchLoop(key: string, ref: HotCollectionRef): Promise<void> {\n let backoff = 0;\n while (!this.stopped) {\n // A stream that stayed healthy for a long time before failing is an\n // isolated blip — reset the escalation instead of converging to 5s\n // forever (backoff is for repeated failures, not for uptime history).\n let connectedAt = Date.now();\n try {\n const db = resolveDbSafe(ref, this.host.logger);\n if (!db) throw new Error('watch db accessor not available');\n const stream = db.collection(ref.collection).watch([]);\n stream.on('error', (err: unknown) => {\n // Prevent EventEmitter crashes between events; keep diagnostics.\n this.host.logger.debug?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'hot cache change stream error event',\n );\n });\n this.streams.set(key, stream);\n connectedAt = Date.now();\n if (backoff > 0) {\n // This stream is a RECONNECT after an error — changes made during the\n // outage were missed, so drop any entries they may have affected.\n this.host.logger.warn?.(\n { collection: ref.collection },\n 'hot cache: change stream reconnected — invalidating collection to drop entries missed during the outage',\n );\n this.host.invalidateCollection(ref.collection);\n }\n const iterator = stream[Symbol.asyncIterator]();\n for await (const change of iterator) {\n // Document events carry `documentKey._id` → targeted purge of just\n // the entries depending on that document (queries without an\n // `idsOf` extractor still get the coarse collection-wide drop, see\n // HotCache.invalidateIds). Anything else (drop/rename/invalidate)\n // purges the whole collection.\n const docId = documentKeyOf(change);\n if (docId === undefined) this.host.invalidateCollection(ref.collection);\n else this.host.invalidateDocument(ref.collection, docId);\n }\n } catch (err) {\n if (Date.now() - connectedAt > 60_000) backoff = 0;\n const message = err instanceof Error ? err.message : String(err);\n this.host.logger.warn?.(\n { error: message, collection: ref.collection },\n 'hot cache change stream error',\n );\n // Close the abandoned stream before the retry loop re-opens one, so a\n // transient error never leaks a ChangeStream cursor.\n const abandoned = this.streams.get(key);\n this.streams.delete(key);\n if (abandoned) {\n try {\n await abandoned.close();\n } catch {\n // Best-effort: the server drops the cursor on disconnect anyway.\n }\n }\n // Classify permanent errors ONLY by the definitive standalone + auth\n // verdicts (see isPermanentWatchError). A broad pattern (e.g. `not\n // supported` or `ChangeStream`) can misfire on replica errors like\n // \"change stream history lost\" (resume-token expiry) and wrongly flip\n // the cache to the standalone ticker — those must stay in the retry\n // path, where the invalidate-on-reopen restores correctness.\n if (isPermanentWatchError(message)) {\n this.markStreamFailed(key, explainPermanentWatchError(message));\n return;\n }\n }\n if (this.stopped) return;\n backoff = Math.min(backoff + 1000, 5000);\n await sleepJittered(backoff, 1000, true);\n }\n }\n\n private markStreamFailed(key: string, verdict?: PermanentWatchExplanation): void {\n this.failedStreams.add(key);\n if (!this.host.isReplica()) return;\n const planned = this.plannedStreamKeys();\n if (planned.size > 0 && [...planned].every((k) => this.failedStreams.has(k))) {\n this.host.logger.warn?.(\n verdict === undefined ? {} : { reason: verdict.reason, hint: verdict.hint },\n `hot cache: change streams unsupported${verdict === undefined ? '' : ` — ${verdict.headline}`}, falling back to ticker`,\n );\n this.host.fallbackToStandalone();\n }\n }\n\n private plannedStreamKeys(): Set<string> {\n const set = new Set<string>();\n for (const q of this.host.queries().values()) {\n for (const ref of q.config.watch ?? []) {\n const db = resolveDbSafe(ref, this.host.logger);\n if (!db) continue; // accessor not ready — not a \"failed\" stream\n set.add(`${db.databaseName}${WATCH_SEP}${ref.collection}`);\n }\n }\n return set;\n }\n}\n","/**\n * HotCache — read-through hot cache for latency-sensitive, high-throughput\n * workloads that cannot afford a DB round-trip on every read.\n *\n * A user creates ONE global instance via `createHotCache()`, opts-in (\"registers\")\n * the queries that should be served from memory, and the parameters of each call\n * become the cache key. Reads hit a per-query LRU; misses run the user's loader\n * exactly once (concurrent identical calls are in-flight-deduped).\n *\n * Keeping the cache fresh is deployment-dependent, chosen by probing whether the\n * MongoDB deployment supports replica sets:\n * - **Replica set / mongos** → change-stream watchers (`./watcher.ts`) are\n * opened on the collections each query is bound to (`watch`). Any\n * insert/update/delete invalidates the affected queries immediately\n * (event-driven, works across processes, covers external writers). When a\n * watch ref declares `idsOf`, the changed document's `_id` is matched\n * against the dependencies each cached entry extracted from its arguments,\n * so only entries that actually depend on the changed document are purged.\n * - **Standalone** (no change streams) → a single global ticker (`./ticker.ts`)\n * background-refreshes cached entries on a set interval. Stale values keep\n * being served until the fresh value swaps in (bounded staleness, reads\n * never block).\n *\n * Both modes (and any code path that knows better than the streams — e.g. ORM\n * after-write hooks) share one fine-tuned purge primitive: `invalidateIds(collection, ids)`\n * drops exactly the entries depending on those documents; `invalidateCollection`\n * stays the coarse \"drop everything watching this collection\" switch.\n *\n * `start()` resolves the mode once; `stop()` is **terminal** — it tears down\n * the ticker + streams and disposes the instance, so a later `get()` serves\n * cached values read-through without ever re-probing or re-opening background\n * resources. Errors from a loader are never cached, so a transient failure\n * retries on the next read.\n *\n * ## Failure semantics (the staleness window)\n *\n * Freshness is best-effort under failure; the cache keeps serving from memory\n * while the background freshness mechanism is down, so **low latency can hide\n * stale reads**. The guarantees:\n *\n * - **Replica (change streams)** — the watcher self-heals: any stream error or\n * server-side kill (resume-token expiry, rollback, replica failover, dropped\n * collection) closes the stream, retries with jittered backoff (1s → 5s),\n * and **invalidates the bound collection once on reopen**, so entries that\n * could have gone stale during the outage are re-fetched on the next read.\n * Until that reopen happens, cached values are served as-is.\n * - **Standalone (ticker)** — entries are background-refreshed only for\n * queries that set `refreshIntervalMs`; a stale value keeps being served\n * until the fresh value swaps in. Queries with neither `refreshIntervalMs`\n * nor `ttlMs` are served until manually invalidated (unbounded staleness;\n * `start()` logs a warning naming them).\n * - **Bounding the window** — set per-query `ttlMs` and/or `refreshIntervalMs`\n * (or `autoRefresh: false` + manual invalidation) and monitor `stats()` plus\n * the \"change stream reconnected\"/\"change stream error\" warnings to bound how\n * long a stale value can be served.\n *\n * This file is the coordinator: public API + the shared read/fetch pipeline.\n * The two freshness strategies and the size estimator live in sibling modules\n * (`./watcher.ts`, `./ticker.ts`, `./size.ts`) and are injected here, keeping\n * each concern small and independently testable.\n */\nimport { probeMongoCapabilities } from '../../capabilities.ts';\nimport { BadRequest } from '../../errors/index.ts';\nimport { cloneDeep } from '../../utils/clone.ts';\nimport { stableHash } from '../../utils/hash.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { LRU } from '../../utils/lru.ts';\nimport { InFlight } from '../in-flight.ts';\nimport { estimateSize } from './size.ts';\nimport { RefreshTicker } from './ticker.ts';\nimport {\n type Entry,\n type HotCacheMode,\n type HotCacheOptions,\n type HotCacheStats,\n type HotQueryAccessor,\n type HotQueryConfig,\n type HotQueryStats,\n normalizeWatchId,\n type RegisteredQuery,\n resolveWatchDb,\n WATCH_SEP,\n} from './types.ts';\nimport { WatchCoordinator } from './watcher.ts';\n\nexport class HotCache {\n private options: HotCacheOptions;\n private logger: LoggerLike;\n private refreshEnabled: boolean;\n private queries = new Map<string, RegisteredQuery>();\n private inflight = new InFlight();\n private watcher: WatchCoordinator;\n private ticker: RefreshTicker;\n private _mode: HotCacheMode = 'unknown';\n private started = false;\n private startAttempted = false;\n private stopped = false;\n private disposed = false;\n private startPromise: Promise<HotCacheMode> | undefined;\n\n constructor(options: HotCacheOptions = {}) {\n this.options = options;\n this.refreshEnabled = options.autoRefresh !== false;\n this.logger = options.logger ?? { debug() {}, info() {}, warn() {}, error() {} };\n this.ticker = new RefreshTicker(\n {\n queries: () => this.queries,\n fetch: (q, key, args, gen) => this.fetch(q, key, args, gen),\n logger: this.logger,\n },\n options.tickIntervalMs ?? 1000,\n );\n this.watcher = new WatchCoordinator({\n queries: () => this.queries,\n invalidateCollection: (collection) => this.invalidateCollection(collection),\n invalidateDocument: (collection, id) => this.invalidateIds(collection, [id]),\n isReplica: () => this._mode === 'replica',\n fallbackToStandalone: () => {\n this._mode = 'standalone';\n if (this.refreshEnabled && !this.ticker.running) {\n this.ticker.start();\n // Late-registered queries never get the start()-time warning; the\n // fallback path must warn for currently-registered unbounded ones too.\n this.ticker.warnUnboundedStaleness();\n }\n },\n logger: this.logger,\n });\n }\n\n /** Number of cached entries across all registered queries. */\n get size(): number {\n let total = 0;\n for (const q of this.queries.values()) total += q.lru.size;\n return total;\n }\n\n /** Resolved mode: `unknown` until `start()` (or the first `get`) probes. */\n get mode(): HotCacheMode {\n return this._mode;\n }\n\n /** Whether the standalone background-refresh ticker is enabled (`autoRefresh`). */\n get autoRefresh(): boolean {\n return this.refreshEnabled;\n }\n\n /** Whether a query with this name has been registered. */\n has(name: string): boolean {\n return this.queries.has(name);\n }\n\n /**\n * Opt a query into the hot cache. Throws `BadRequest` on a duplicate name.\n * Returns a fully typed accessor — `.get(...args)` (intellisense on the loader\n * parameters) and `.invalidate()` / `.invalidate(...args)` for manual\n * invalidation (all entries or a single parameter set).\n */\n register<TArgs extends readonly unknown[], TResult>(\n name: string,\n config: HotQueryConfig<TArgs, TResult>,\n ): HotQueryAccessor<TArgs, TResult> {\n if (this.queries.has(name)) {\n throw new BadRequest(`hot cache: query '${name}' is already registered`);\n }\n const query: RegisteredQuery = {\n name,\n config: config as HotQueryConfig<readonly unknown[], unknown>,\n lru: new LRU<string, Entry>({\n max: config.maxSize ?? this.options.defaultMaxSize ?? 500,\n }),\n ttlMs: config.ttlMs ?? this.options.defaultTtlMs ?? 0,\n refreshIntervalMs: config.refreshIntervalMs ?? 0,\n clone: config.clone ?? false,\n ...(config.maxValueBytes !== undefined ? { maxValueBytes: config.maxValueBytes } : {}),\n hasIdWatch: (config.watch ?? []).some((ref) => typeof ref.idsOf === 'function'),\n gen: 0,\n hits: 0,\n misses: 0,\n refreshes: 0,\n loadErrors: 0,\n sizeSkips: 0,\n idDrops: 0,\n warnedSize: false,\n };\n this.queries.set(name, query);\n // If already running in replica mode, wire change streams for new watch refs.\n if (this._mode === 'replica' && !this.stopped) {\n this.watcher.start();\n }\n // Named consts (not inline arrows) so stack frames read `get`/`invalidate`\n // instead of `<anonymous>` when user code goes through the accessor.\n const get = (...args: TArgs): Promise<TResult> => this.get(name, ...args) as Promise<TResult>;\n const invalidate = (...args: TArgs): void => {\n if (args.length === 0) this.invalidate(name);\n else this.invalidateParams(name, ...args);\n };\n return { get, invalidate };\n }\n\n /**\n * Read-through read by dynamic name lookup. Call parameters are hashed into\n * the cache key (`keyOf` override wins). Throws `BadRequest` for an unknown\n * query name. For fully typed parameters/results prefer the accessor returned\n * by `register()` — this dynamic form returns `Promise<unknown>`.\n */\n async get(name: string, ...args: unknown[]): Promise<unknown> {\n this.ensureStarted();\n const q = this.queries.get(name);\n if (!q) throw new BadRequest(`hot cache: unknown query '${name}'`);\n const key = q.config.keyOf ? q.config.keyOf(...args) : stableHash(args);\n const entry = q.lru.get(key);\n if (entry && !(q.ttlMs > 0 && entry.expiresAt <= Date.now())) {\n q.hits++;\n // Each read gets its own copy so the stored entry can't be mutated.\n return q.clone ? cloneDeep(entry.value) : entry.value;\n }\n if (entry && q.ttlMs > 0 && entry.expiresAt <= Date.now()) {\n // Drop the dead entry eagerly so `size`/`stats()` stay accurate.\n q.lru.delete(key);\n }\n q.misses++;\n // `await` (not a bare `return`): a non-awaited return from an async\n // function unwinds the caller chain in Bun's stack capture, so the ignex\n // debugbar's span origin would truncate here and never reach the route\n // handler that issued this read.\n return await this.fetch(q, key, args, q.gen);\n }\n\n /** Drop every cached entry for a registered query. */\n invalidate(name: string): void {\n const q = this.queries.get(name);\n if (!q) return;\n q.lru.clear();\n q.gen++;\n }\n\n /**\n * Drop only the cached entry for a specific parameter set. The key is computed\n * exactly like `get` (`keyOf` override ?? `stableHash` of args), so the same\n * parameters invalidate the same entry.\n */\n invalidateParams(name: string, ...args: unknown[]): void {\n const q = this.queries.get(name);\n if (!q) return;\n const key = q.config.keyOf ? q.config.keyOf(...args) : stableHash(args);\n q.lru.delete(key);\n q.gen++;\n }\n\n /**\n * Invalidate every query bound to a physical collection (via `watch`). Can be\n * called manually to wire ORM write hooks in standalone mode.\n */\n invalidateCollection(collection: string): void {\n for (const q of this.queries.values()) {\n if (q.config.watch?.some((ref) => ref.collection === collection)) {\n q.lru.clear();\n q.gen++;\n }\n }\n }\n\n /**\n * Fine-tuned purge: drop only the entries that depend on specific document\n * ids of a watched collection. Two complementary mechanisms feed it:\n *\n * - **Replica mode** — the change stream extracts `documentKey._id` from\n * each event and calls this with just that id, so a write to one document\n * no longer purges every query bound to the whole collection.\n * - **Manual (any mode)** — call it from ORM after-write hooks or anywhere\n * else you know exactly which ids changed.\n *\n * Per query bound to `collection`, semantics are:\n * - watch ref declares `idsOf` → only LRU entries whose extracted ids\n * include one of `ids` are dropped (`depsAll` entries — where extraction\n * failed — are dropped too; conservative). Sibling entries stay warm and\n * `stats().perQuery[name].idDrops` counts what was dropped.\n * - no `idsOf` on any bound ref → full purge of that query (the\n * `invalidateCollection` behavior — the safe default).\n */\n invalidateIds(collection: string, ids: readonly unknown[]): void {\n if (ids.length === 0) return;\n // Deps are stored namespaced (`${collection}${WATCH_SEP}${id}`) so\n // multi-collection watchers never cross-invalidate — match that exact shape.\n const changed = new Set<string>();\n for (const id of ids) changed.add(`${collection}${WATCH_SEP}${normalizeWatchId(id)}`);\n for (const q of this.queries.values()) {\n const bound = q.config.watch?.filter((ref) => ref.collection === collection);\n if (!bound || bound.length === 0) continue;\n if (!bound.some((ref) => typeof ref.idsOf === 'function')) {\n // No id-level extractor for this collection → keep the coarse contract.\n q.lru.clear();\n q.gen++;\n continue;\n }\n let dropped = 0;\n for (const [key, entry] of [...q.lru.entries()]) {\n const matches =\n entry.depsAll === true || entry.deps?.some((dep) => changed.has(dep)) === true;\n if (matches) {\n q.lru.delete(key);\n dropped++;\n }\n }\n q.idDrops += dropped;\n // Unconditional race guard (even when nothing was dropped): an in-flight\n // load for these args must never re-store a value fetched BEFORE the\n // change event — otherwise a change landing mid-load would pin the old\n // value in the cache with no TTL to rescue it.\n q.gen++;\n }\n }\n\n /** Drop every cached entry for every query. */\n clear(): void {\n for (const q of this.queries.values()) {\n q.lru.clear();\n q.gen++;\n }\n }\n\n /**\n * Runtime observability snapshot: total queries/entries plus per-query\n * counters (`hits`, `misses`, background `refreshes`, `loadErrors`,\n * `sizeSkips` for entries dropped by `maxValueBytes`, and `idDrops` for\n * entries dropped by id-targeted invalidation). Useful for dashboards and\n * cache-effectiveness checks.\n */\n stats(): HotCacheStats {\n const perQuery: Record<string, HotQueryStats> = {};\n for (const [name, q] of this.queries) {\n perQuery[name] = {\n size: q.lru.size,\n hits: q.hits,\n misses: q.misses,\n refreshes: q.refreshes,\n loadErrors: q.loadErrors,\n sizeSkips: q.sizeSkips,\n idDrops: q.idDrops,\n evictions: q.lru.evictions,\n };\n }\n return { mode: this._mode, queries: this.queries.size, entries: this.size, perQuery };\n }\n\n /**\n * Probe replica support once, then start change-stream watchers (replica) or\n * the global refresh ticker (standalone). Idempotent — resolves the mode.\n * A FAILED start does not stick: the memoized promise is cleared so the next\n * `get()`/`start()` retries probing (one transient blip during startup must\n * not disable background freshness for the life of the instance).\n */\n async start(): Promise<HotCacheMode> {\n if (this.disposed) return this._mode;\n if (this.started) return this._mode;\n if (!this.startPromise) {\n this.startPromise = this.runStart().catch(this.forgetFailedStart);\n }\n return this.startPromise;\n }\n\n /**\n * Stop the ticker, close every change stream, and **dispose** the instance.\n * Terminal: a later `get()` serves cached values read-through but never\n * re-probes or re-opens background resources.\n */\n async stop(): Promise<void> {\n this.disposed = true;\n this.stopped = true;\n this.ticker.stop();\n await this.watcher.stop();\n this.inflight.clear();\n // In-flight loads shouldn't re-populate the cache during/after teardown.\n for (const q of this.queries.values()) q.gen++;\n this.started = false;\n this.startAttempted = false;\n this.startPromise = undefined;\n this._mode = 'unknown';\n }\n\n /* ----------------------------- internals ----------------------------- */\n\n /**\n * A FAILED start does not stick: clear the memoized state so the next\n * `get()`/`start()` retries probing (one transient blip during startup must\n * not disable background freshness for the life of the instance).\n */\n private forgetFailedStart = (err: unknown): never => {\n this.startPromise = undefined;\n this.startAttempted = false;\n this.started = false;\n throw err;\n };\n\n private async runStart(): Promise<HotCacheMode> {\n this.stopped = false;\n const supported =\n this.options.mode === 'replica'\n ? true\n : this.options.mode === 'standalone'\n ? false\n : await (this.options.probe ?? this.defaultProbe)();\n // stop() may have run while the probe was in flight — don't re-open resources.\n if (this.disposed) {\n this.started = false;\n return this._mode;\n }\n if (supported) {\n this._mode = 'replica';\n this.watcher.start();\n } else {\n this._mode = 'standalone';\n if (this.refreshEnabled) {\n this.ticker.start();\n this.ticker.warnUnboundedStaleness();\n }\n }\n this.started = true;\n return this._mode;\n }\n\n private ensureStarted(): void {\n if (this.disposed || this.started || this.startAttempted) return;\n this.startAttempted = true;\n // Fire-and-forget: the rejection crosses a promise boundary, so the error's\n // own stack will NOT contain whoever triggered this read. Snapshot the\n // synchronous caller chain NOW and attach it as `cause` + log meta —\n // otherwise \"start failed\" warnings are unattributable.\n const origin = new Error('hot cache: background start() was triggered by this call');\n const reportStartFailure = (err: unknown): void => {\n const wrapped = err instanceof Error ? err : new Error(String(err));\n if (wrapped.cause === undefined) wrapped.cause = origin;\n this.logger.warn?.(\n { error: wrapped.message, stack: wrapped.stack, trigger: origin.stack },\n 'hot cache start failed; reads continue without auto-refresh',\n );\n };\n this.start().catch(reportStartFailure);\n }\n\n private defaultProbe = async (): Promise<boolean> => {\n for (const q of this.queries.values()) {\n for (const ref of q.config.watch ?? []) {\n let db: { databaseName: string };\n try {\n db = resolveWatchDb(ref);\n } catch {\n // Lazy accessor not ready (module-scope registration before connect)\n // — treat as \"unknown\", not standalone.\n this.logger.warn?.(\n {},\n 'hot cache: replica probe could not resolve the watch db (accessor threw) — falling back to the standalone ticker; pass `mode` or a custom `probe` to pin the behavior',\n );\n return false;\n }\n const caps = await probeMongoCapabilities(db as never);\n if (!caps.probed) {\n // A timed-out/failed probe is NOT \"confirmed standalone\" — falling back\n // to the ticker silently could surprise replica users. Warn loudly so\n // they can pin the behavior with `mode` or a custom `probe`.\n this.logger.warn?.(\n { db: db.databaseName },\n 'hot cache: replica probe returned no result (timeout?) — falling back to the standalone ticker; pass `mode` or a custom `probe` to pin the behavior',\n );\n return false;\n }\n return caps.transactionsSupported;\n }\n }\n return false;\n };\n\n private fetch(\n q: RegisteredQuery,\n key: string,\n args: readonly unknown[],\n gen: number,\n ): Promise<unknown> {\n // The generation is part of the dedup identity: a reader arriving AFTER an\n // invalidation must start a FRESH load, never join the pre-invalidation\n // in-flight one (whose result is stale-by-arrival for it).\n const dedupeKey = `${q.name}${WATCH_SEP}g${gen}${WATCH_SEP}${key}`;\n // Named const (not an inline async arrow) so loader frames read `loadOnce`\n // instead of `<anonymous>` in error stacks.\n const loadOnce = async (): Promise<unknown> => {\n try {\n const value = await q.config.loader(...args);\n // Generation guard: if an invalidation/clear happened while the loader\n // was in flight, the result is stale-by-arrival — don't re-store it.\n // The caller still receives the value; the next read re-fetches.\n if (q.gen === gen) {\n const bytes = q.maxValueBytes !== undefined ? estimateSize(value) : undefined;\n if (bytes !== undefined && bytes > q.maxValueBytes!) {\n q.sizeSkips++;\n if (!q.warnedSize) {\n q.warnedSize = true;\n this.logger.warn?.(\n { query: q.name, bytes, max: q.maxValueBytes },\n 'hot cache: value exceeds maxValueBytes — returned but not cached',\n );\n }\n } else {\n this.setEntry(q, key, args, value);\n }\n }\n return value;\n } catch (err) {\n q.loadErrors++;\n throw err;\n }\n };\n return this.inflight.run<unknown>(dedupeKey, loadOnce);\n }\n\n private setEntry(\n q: RegisteredQuery,\n key: string,\n args: readonly unknown[],\n value: unknown,\n ): void {\n const now = Date.now();\n // Id-level watch: record which watched documents this result depends on, so\n // `invalidateIds` (change stream or manual) can purge exactly these entries.\n const deps = q.hasIdWatch ? this.computeDeps(q, args) : {};\n q.lru.set(key, {\n value,\n args,\n expiresAt: q.ttlMs > 0 ? now + q.ttlMs : Infinity,\n nextRefreshAt: q.refreshIntervalMs > 0 ? now + q.refreshIntervalMs : Infinity,\n ...deps,\n });\n }\n\n /**\n * Extract the watched-document dependencies of one loader call. Namespaced by\n * collection so multi-collection watchers never cross-invalidate. An extractor\n * that throws or returns a non-array yields `{ depsAll: true }` — the entry is\n * then dropped by ANY targeted change on its watched collections instead of\n * being incorrectly kept.\n */\n private computeDeps(\n q: RegisteredQuery,\n args: readonly unknown[],\n ): Pick<Entry, 'deps' | 'depsAll'> {\n const deps: string[] = [];\n for (const ref of q.config.watch ?? []) {\n if (!ref.idsOf) continue;\n // The `never`-params declaration is contravariance-safe for writers; the\n // runtime contract is that it accepts the loader's argument tuple.\n const extract = ref.idsOf as (...args: readonly unknown[]) => readonly unknown[];\n try {\n const ids = extract(...args);\n if (!Array.isArray(ids)) return { depsAll: true };\n for (const id of ids) deps.push(`${ref.collection}${WATCH_SEP}${normalizeWatchId(id)}`);\n } catch {\n return { depsAll: true };\n }\n }\n return { deps };\n }\n}\n\n/** Create a new global hot-cache instance. */\nexport const createHotCache = (options?: HotCacheOptions): HotCache => new HotCache(options);\n\n// Re-export the public HotCache types so the folder barrel matches the old\n// single-module exports.\nexport type {\n Entry,\n HotCacheMode,\n HotCacheOptions,\n HotCacheStats,\n HotCollectionRef,\n HotQueryAccessor,\n HotQueryConfig,\n HotQueryStats,\n RegisteredQuery,\n} from './types.ts';\n","import { cloneDeep } from '../utils/clone.ts';\nimport { LRU } from '../utils/lru.ts';\n\nexport interface QueryCacheOptions {\n /** Max cached entries (default 500). */\n maxSize?: number;\n /** Per-entry TTL in ms (default 30_000; set 0 explicitly for no expiry). */\n ttlMs?: number;\n /**\n * Clone results on every read so callers can't mutate the shared cache entry\n * (default true; set false only for read-only results where zero-copy matters).\n */\n clone?: boolean;\n}\n\ninterface Entry<V> {\n value: V;\n expiresAt: number;\n /**\n * Per-source-collection version at READ start (see `versionOf`). When an\n * invalidation bumps a collection's version while a read is in-flight, the\n * stored version no longer matches and `get()` treats the entry as stale —\n * this is the write-after-invalidate race guard (mirrors HotCache's `gen`).\n */\n versions?: Record<string, number>;\n}\n\n/** Snapshot of cache health (see `QueryCache.stats()`). */\nexport interface QueryCacheStats {\n size: number;\n maxSize: number;\n /** Reads served from the cache without touching the DB. */\n hits: number;\n /** Reads that missed (absent or expired). */\n misses: number;\n /** `set()` calls (writes to the cache). */\n sets: number;\n /** `delete()` calls. */\n deletes: number;\n /** `invalidateByCollection` calls that actually dropped entries. */\n invalidateEvents: number;\n /** `clear()` calls. */\n clearEvents: number;\n /** Capacity evictions (LRU). */\n evictions: number;\n}\n\nconst SEP = '\\u0000';\n/** Namespace separator between the database name and physical collection. */\nconst NS_SEP = '\\u0001';\n\n/**\n * Compose the collection part of a cache key, namespaced by deployment and DB.\n * One service shares a QueryCache + InFlight across every client; without these\n * namespaces, same-named physical collections in different databases/clusters\n * would collide — a read on DB A could be served DB B's cached rows, and identical\n * concurrent reads across DBs could coalesce into one driver call. Reads,\n * write-through invalidations, and change-stream invalidations MUST all use the\n * same namespace so they agree.\n */\nexport const cacheCollectionKey = (\n dbName: string,\n physical: string,\n clusterNamespace = '',\n): string => `${clusterNamespace}${NS_SEP}${dbName}${NS_SEP}${physical}`;\n\n/**\n * Read-through query cache with per-collection invalidation.\n *\n * Keys are `collection<sep>hash` so a single write can invalidate every cached\n * read for that collection. `set()` can also register an entry under ADDITIONAL\n * collection keys (see `collections`) so derived reads — e.g. an aggregation\n * with `$lookup`/`$unionWith` — are invalidated when ANY of their source\n * collections changes. Invalidation is WRITE-THROUGH only: the ORM drops a\n * collection's entries on every write it performs. Reads are NOT invalidated by\n * external writers (other processes, the raw `client` escape hatch, or direct\n * DB writes). The default 30-second TTL bounds staleness; `ttlMs: 0` explicitly\n * disables expiry, so multi-writer deployments can also use the change-stream aware\n * `createHotCache()`. Perf wins: cache hits perform zero driver round-trips.\n */\nexport class QueryCache {\n private lru: LRU<string, Entry<unknown>>;\n private index = new Map<string, Set<string>>();\n /**\n * Reverse index: key → every collection it is registered under. Without it,\n * keys dropped by TTL expiry / capacity eviction / version-guard would stay\n * listed in `index` forever (unbounded growth + O(dead) invalidation scans).\n */\n private keyCollections = new Map<string, Set<string>>();\n /** Per-collection version — bumped on every invalidation/clear of that collection. */\n private colVersions = new Map<string, number>();\n private ttlMs: number;\n private clone: boolean;\n private hits = 0;\n private misses = 0;\n private sets = 0;\n private deletes = 0;\n private invalidateEvents = 0;\n private clearEvents = 0;\n\n constructor(options: QueryCacheOptions = {}) {\n this.lru = new LRU<string, Entry<unknown>>({\n max: options.maxSize ?? 500,\n onEvict: (key) => this.unregisterKey(key),\n });\n this.ttlMs = options.ttlMs ?? 30_000;\n this.clone = options.clone ?? true;\n }\n\n get size(): number {\n return this.lru.size;\n }\n\n /** Cache-health snapshot: sizes plus lifetime hit/miss/eviction counters. */\n stats(): QueryCacheStats {\n return {\n size: this.lru.size,\n maxSize: this.lru.max,\n hits: this.hits,\n misses: this.misses,\n sets: this.sets,\n deletes: this.deletes,\n invalidateEvents: this.invalidateEvents,\n clearEvents: this.clearEvents,\n evictions: this.lru.evictions,\n };\n }\n\n /** Compose a cache key for a collection + filter/options hash. */\n key(collection: string, filterHash: string): string {\n return `${collection}${SEP}${filterHash}`;\n }\n\n /**\n * Current version of a collection key (db-namespaced, e.g. from\n * `cacheCollectionKey`). Reads capture it BEFORE fetching and pass it to\n * `set()` so a concurrent invalidation can never be hidden by a late write.\n */\n versionOf(collection: string): number {\n return this.colVersions.get(collection) ?? 0;\n }\n\n get(key: string): unknown | undefined {\n const entry = this.lru.get(key);\n if (!entry) {\n this.misses++;\n return undefined;\n }\n if (this.ttlMs > 0 && Date.now() > entry.expiresAt) {\n this.dropKey(key);\n this.misses++;\n return undefined;\n }\n // Write-after-invalidate guard: if any source collection was invalidated\n // after this entry was computed (its stored version lags the current one),\n // the value is stale-by-arrival — drop it and force a re-fetch.\n if (entry.versions) {\n for (const [col, ver] of Object.entries(entry.versions)) {\n if (this.versionOf(col) !== ver) {\n this.dropKey(key);\n this.misses++;\n return undefined;\n }\n }\n }\n this.hits++;\n // Each read gets its own copy so the stored entry can't be mutated.\n return this.clone ? cloneDeep(entry.value) : entry.value;\n }\n\n /** Remove a key from the LRU and every collection index that references it. */\n private dropKey(key: string): void {\n this.lru.delete(key);\n this.unregisterKey(key);\n }\n\n /** Remove `key` from `index` (called for evictions AND explicit drops). */\n private unregisterKey(key: string): void {\n const collections = this.keyCollections.get(key);\n if (!collections) return;\n this.keyCollections.delete(key);\n for (const collection of collections) {\n const keys = this.index.get(collection);\n if (!keys) continue;\n keys.delete(key);\n if (keys.size === 0) this.index.delete(collection);\n }\n }\n\n set(\n key: string,\n value: unknown,\n ttlMs?: number,\n collections?: string[],\n versions?: Record<string, number>,\n ): void {\n this.sets++;\n const ttl = ttlMs ?? this.ttlMs;\n const expiresAt = ttl > 0 ? Date.now() + ttl : Infinity;\n this.unregisterKey(key);\n this.lru.set(key, {\n value,\n expiresAt,\n ...(versions !== undefined ? { versions } : {}),\n });\n // Primary collection is derived from the key prefix. `collections` lists\n // ADDITIONAL source collections the entry depends on (e.g. the `$lookup`\n // join target of a cached aggregation) — registering the key under each\n // means a write to ANY source drops the entry. The reverse index keeps\n // both sides in sync so evictions/expiry never leak dead references.\n const sep = key.indexOf(SEP);\n const primary = sep === -1 ? key : key.slice(0, sep);\n const collectionKeys = new Set<string>([primary, ...(collections ?? [])]);\n this.keyCollections.set(key, collectionKeys);\n for (const collection of collectionKeys) {\n let keys = this.index.get(collection);\n if (!keys) {\n keys = new Set<string>();\n this.index.set(collection, keys);\n }\n keys.add(key);\n }\n }\n\n delete(key: string): void {\n this.deletes++;\n this.dropKey(key);\n }\n\n /** Drop every cached entry belonging to a physical collection. */\n invalidateByCollection(collection: string): void {\n // Bump the collection version BEFORE dropping, so any in-flight read that\n // started earlier can never re-store a stale value (see `get` guard).\n this.colVersions.set(collection, (this.colVersions.get(collection) ?? 0) + 1);\n const keys = this.index.get(collection);\n if (!keys) return;\n this.invalidateEvents++;\n // dropKey also unregisters each key from its OTHER source collections\n // (e.g. a `$lookup` entry listed under both sides) — no dead refs left.\n for (const key of [...keys]) this.dropKey(key);\n this.index.delete(collection);\n }\n\n clear(): void {\n this.clearEvents++;\n // Bump every known collection so in-flight reads can't re-store stale\n // values past a clear() either.\n for (const collection of this.index.keys()) {\n this.colVersions.set(collection, (this.colVersions.get(collection) ?? 0) + 1);\n }\n this.lru.clear();\n this.index.clear();\n this.keyCollections.clear();\n }\n}\n","import type { ClientSession } from 'mongodb';\nimport {\n type createMongoCapabilitiesStore,\n readMongoTransactionsEnvOverride,\n} from './capabilities.ts';\nimport { InfraError, isTransactionUnsupportedError, mapMongoDriverError } from './errors/index.ts';\nimport type { LoggerLike } from './utils/logger.ts';\n\n/** Minimal transaction runner surface (satisfied by the service `transaction`). */\nexport interface MongoTransactionRunner {\n transaction: <T>(\n fn: (session: ClientSession | null) => Promise<T>,\n options?: { allowNonTransactionalFallback?: boolean },\n ) => Promise<T>;\n}\n\nexport interface GracefulTransactionOptions {\n capabilities?: ReturnType<typeof createMongoCapabilitiesStore>;\n urlHint?: string;\n logger?: LoggerLike;\n /** Map driver errors to typed DomainError/InfraError before rethrowing (default true). */\n wrapMongoErrors?: boolean;\n /** Explicitly permit non-atomic execution on deployments without transactions. */\n allowNonTransactionalFallback?: boolean;\n}\n\n/**\n * Run `fn` inside a transaction. Unsupported deployments throw unless\n * `allowNonTransactionalFallback: true` explicitly permits a `null` session.\n *\n * When capability state is UNKNOWN (probe failed/timed out and no URL hint or\n * env override says otherwise), we ATTEMPT the real transaction rather than\n * silently downgrading — a transient startup blip must not turn an atomic\n * write into a non-atomic one. The catch path still falls back cleanly on a\n * genuinely unsupported deployment only after explicit opt-in.\n */\nexport const withGracefulMongoTransaction = async <T>(\n runner: MongoTransactionRunner,\n fn: (session: ClientSession | null) => Promise<T>,\n options: GracefulTransactionOptions = {},\n): Promise<T> => {\n let enabled = true;\n if (options.capabilities !== undefined) {\n const env = readMongoTransactionsEnvOverride();\n if (env !== undefined) {\n enabled = env;\n } else {\n const state = options.capabilities.get();\n if (state.probed) {\n enabled = state.transactionsSupported;\n } else if (options.urlHint) {\n enabled = /replicaSet=|mongodb\\+srv:/i.test(options.urlHint);\n } // else UNKNOWN → keep `true` and let the attempt/fallback decide.\n }\n }\n const unsupported = () =>\n new InfraError(\n 'TRANSACTIONS_UNSUPPORTED',\n 'MongoDB deployment does not support transactions; set allowNonTransactionalFallback to run non-atomically',\n );\n if (!enabled) {\n if (options.allowNonTransactionalFallback === true) return fn(null);\n throw unsupported();\n }\n\n try {\n return await runner.transaction(fn, {\n ...(options.allowNonTransactionalFallback !== undefined\n ? { allowNonTransactionalFallback: options.allowNonTransactionalFallback }\n : {}),\n });\n } catch (err) {\n if (isTransactionUnsupportedError(err)) {\n if (options.allowNonTransactionalFallback !== true) throw err;\n options.logger?.warn?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'transactions unsupported; running explicitly requested non-transactional fallback',\n );\n return fn(null);\n }\n if (options.wrapMongoErrors !== false) {\n throw mapMongoDriverError(err, { op: 'transaction' });\n }\n throw err;\n }\n};\n","import type { Document, Filter } from 'mongodb';\n\n/**\n * Lifecycle hooks — the ORM's middleware system. Hooks are declared per\n * collection and run around the corresponding CRUD operation.\n */\nexport type HookName =\n | 'beforeCreate'\n | 'afterCreate'\n | 'beforeUpdate'\n | 'afterUpdate'\n | 'beforeDelete'\n | 'afterDelete'\n | 'afterRead';\n\nexport interface HookContext<TSchema = Document> {\n collection: string;\n doc?: TSchema;\n docs?: TSchema[];\n filter?: Filter<Document>;\n options?: Record<string, unknown>;\n}\n\nexport type Hook<TSchema = Document> = (ctx: HookContext<TSchema>) => void | Promise<void>;\n\nexport type HookMap<TSchema = Document> = Partial<Record<HookName, Hook<TSchema>>>;\n\n/** Registry keyed by logical collection name. */\nexport type HooksRegistry = Record<string, HookMap>;\n\nexport const HOOK_NAMES: readonly HookName[] = [\n 'beforeCreate',\n 'afterCreate',\n 'beforeUpdate',\n 'afterUpdate',\n 'beforeDelete',\n 'afterDelete',\n 'afterRead',\n];\n\n/** True when a hook is registered for the given collection + name. */\nexport const hasHook = (\n registry: HooksRegistry | undefined,\n collection: string,\n name: HookName,\n): boolean => registry?.[collection]?.[name] !== undefined;\n\n/** Run a single hook (no-op when the collection has none registered). */\nexport const runHooks = async <TSchema = Document>(\n registry: HooksRegistry | undefined,\n collection: string,\n name: HookName,\n ctx: HookContext<TSchema>,\n): Promise<void> => {\n const hooks = registry?.[collection];\n const hook = hooks?.[name];\n if (!hook) return;\n await hook(ctx as HookContext<Document>);\n};\n","/**\n * A self-contained DataLoader — batch + cache loading that eliminates the\n * N+1 query problem (the classic GraphQL utility, implemented from scratch so\n * the ORM owns its batching behavior).\n *\n * Semantics:\n * - concurrent `load(key)` calls made in the same tick are coalesced into ONE\n * `batch(keys)` call (flushed on a microtask, or after `maxBatchDelayMs`)\n * - the batch result is a Map (key → value); a missing key resolves `undefined`\n * - results are cached per key (canonicalized via `keyOf`) for the loader's\n * lifetime; `clear`/`clearAll` reset the cache\n * - a FAILED batch is never cached: its keys are evicted so a later `load`\n * runs a fresh batch instead of re-surfacing the same rejection\n * - `maxBatchSize` splits oversized batches\n */\nimport { stableStringify } from '../utils/hash.ts';\n\nexport interface DataLoaderOptions<Key, Value> {\n /** Resolve a batch of keys → one Map. Keys that have no row should be absent. */\n batch: (keys: Key[]) => Promise<Map<Key, Value>>;\n /** Max keys per batch call (default 1000). */\n maxBatchSize?: number;\n /** Flush delay in ms (default 0 → microtask flush, i.e. one tick batching). */\n maxBatchDelayMs?: number;\n /** Cache loaded values (default true). */\n cache?: boolean;\n /** Canonical key function for value-based keys (ObjectId, Date, ...). */\n keyOf?: (key: Key) => string;\n cacheMap?: Map<string, Promise<Value | undefined>>;\n}\n\ninterface QueueItem<Key, Value> {\n key: Key;\n canonicalKey: string;\n /** The promise returned to the caller — kept so a failed batch can evict exactly this cache entry. */\n promise: Promise<Value | undefined>;\n resolve: (value: Value | undefined) => void;\n reject: (error: unknown) => void;\n}\n\nexport class DataLoader<Key, Value> {\n private readonly batchFn: (keys: Key[]) => Promise<Map<Key, Value>>;\n private readonly maxBatchSize: number;\n private readonly maxBatchDelayMs: number;\n private readonly cacheEnabled: boolean;\n private readonly keyOf: (key: Key) => string;\n private readonly cache: Map<string, Promise<Value | undefined>>;\n\n private queue: Array<QueueItem<Key, Value>> = [];\n private scheduled = false;\n private flushing = false;\n\n constructor(options: DataLoaderOptions<Key, Value>) {\n this.batchFn = options.batch;\n this.maxBatchSize = options.maxBatchSize ?? 1000;\n this.maxBatchDelayMs = options.maxBatchDelayMs ?? 0;\n this.cacheEnabled = options.cache ?? true;\n this.keyOf = options.keyOf ?? ((key: Key): string => `${typeof key}:${String(key)}`);\n this.cache = options.cacheMap ?? new Map();\n }\n\n /** Load one key. Concurrent loads are batched; cached keys resolve instantly. */\n load(key: Key): Promise<Value | undefined> {\n const canonicalKey = this.keyOf(key);\n if (this.cacheEnabled) {\n const cached = this.cache.get(canonicalKey);\n if (cached) return cached;\n }\n\n let resolve!: (value: Value | undefined) => void;\n let reject!: (error: unknown) => void;\n const promise = new Promise<Value | undefined>((res, rej) => {\n resolve = res;\n reject = rej;\n });\n this.queue.push({ key, canonicalKey, promise, resolve, reject });\n if (this.cacheEnabled) this.cache.set(canonicalKey, promise);\n\n this.scheduleFlush();\n return promise;\n }\n\n /** Load many keys (each resolves independently). */\n loadMany(keys: readonly Key[]): Promise<Array<Value | undefined>> {\n return Promise.all(keys.map((key) => this.load(key)));\n }\n\n clear(key: Key): this {\n this.cache.delete(this.keyOf(key));\n return this;\n }\n\n clearAll(): this {\n this.cache.clear();\n return this;\n }\n\n /** Pre-populate the cache without hitting the batch function. */\n prime(key: Key, value: Value): this {\n if (this.cacheEnabled) this.cache.set(this.keyOf(key), Promise.resolve(value));\n return this;\n }\n\n get pendingCount(): number {\n return this.queue.length;\n }\n\n private scheduleFlush(): void {\n if (this.scheduled) return;\n this.scheduled = true;\n if (this.maxBatchDelayMs > 0) {\n setTimeout(() => {\n void this.flush();\n }, this.maxBatchDelayMs);\n } else {\n queueMicrotask(() => {\n void this.flush();\n });\n }\n }\n\n private async flush(): Promise<void> {\n if (this.flushing) {\n // A flush is already running and drained the queue slice; reset the\n // flag so its `finally` re-schedules us for the leftover items.\n this.scheduled = false;\n return;\n }\n if (this.queue.length === 0) {\n this.scheduled = false;\n return;\n }\n\n const items = this.queue.splice(0, this.maxBatchSize);\n this.flushing = true;\n // Re-open the scheduling window BEFORE the batch runs: loads arriving\n // mid-flight then open a fresh `maxBatchDelayMs` window instead of never\n // being scheduled (the old code kept `scheduled` true for the whole\n // batch, collapsing the configured coalescing window after the first one).\n this.scheduled = false;\n try {\n const resultMap = await this.batchFn(items.map((item) => item.key));\n for (const item of items) {\n item.resolve(resultMap.get(item.key));\n }\n } catch (error) {\n for (const item of items) {\n // Never cache a failure: evict this exact promise (guarded by identity\n // so a newer load of the same key created mid-batch is left intact),\n // then reject — a later load will run a fresh batch.\n if (this.cacheEnabled && this.cache.get(item.canonicalKey) === item.promise) {\n this.cache.delete(item.canonicalKey);\n }\n item.reject(error);\n }\n } finally {\n this.flushing = false;\n // Leftover keys (maxBatchSize split / arrivals during the batch) go\n // through the normal scheduler so they honor the configured window.\n if (!this.scheduled && this.queue.length > 0) {\n this.scheduleFlush();\n }\n }\n }\n}\n\n/** Canonical key for value-comparison keys (ObjectId → hex, primitives → typed string). */\nexport const canonicalKey = (value: unknown): string => {\n if (value === undefined || value === null) return 'null';\n if (typeof value === 'object') {\n const anyValue = value as { toHexString?: () => string };\n if (typeof anyValue.toHexString === 'function') return `oid:${anyValue.toHexString()}`;\n if (value instanceof Date) return `date:${value.getTime()}`;\n // Plain objects: deterministic serialization — `String(value)` collapsed\n // every object to \"[object Object]\", making distinct keys collide.\n return `obj:${stableStringify(value)}`;\n }\n return `${typeof value}:${String(value)}`;\n};\n","/**\n * Migration types + constants shared by `./files.ts` (discovery/scaffolding),\n * `./journal.ts` (the `_migrations` journal) and `./index.ts` (the runner).\n */\nimport type { Document } from 'mongodb';\nimport type { LoggerLike } from '../utils/logger.ts';\n\nexport interface MigrationContext {\n service: unknown;\n logger: LoggerLike;\n name: string;\n}\n\nexport interface MigrationModule {\n up: (ctx: MigrationContext) => void | Promise<void>;\n down: (ctx: MigrationContext) => void | Promise<void>;\n}\n\n/** Minimal manager surface the journaling uses (satisfied by `service.db.*Client`). */\nexport interface JournalManager {\n insertOne(collection: string, doc: Document): Promise<unknown>;\n findMany(collection: string, filter?: Document, options?: any): Promise<Document[]>;\n deleteOne(collection: string, filter: Document, options?: any): Promise<unknown>;\n deleteMany(collection: string, filter: Document, options?: any): Promise<unknown>;\n updateOne(\n collection: string,\n filter: Document,\n update: Document,\n options?: any,\n ): Promise<{ matchedCount?: number } | unknown>;\n findOneAndUpdate(\n collection: string,\n filter: Document,\n update: Document,\n options?: Record<string, unknown>,\n ): Promise<Document | null>;\n /** Optional — used to enforce journal-row uniqueness across runners. */\n createIndex?(\n collection: string,\n key: Document,\n options?: Record<string, unknown>,\n ): Promise<unknown>;\n}\n\nexport interface MongoMigrationRunner {\n /** Apply every not-yet-applied migration in numeric order. */\n up(): Promise<void>;\n /**\n * Roll back applied migrations in reverse order (down to `targetName` when\n * given). An unknown `targetName` throws BEFORE anything is rolled back.\n */\n down(targetName?: string): Promise<void>;\n status(): Promise<{ applied: string[]; pending: string[] }>;\n /** Scaffold a new `NNN_name.ts` migration file; returns its path. */\n create(name: string): Promise<string>;\n}\n\nexport interface MongoMigrationRunnerOptions {\n migrationDir?: string;\n logger?: LoggerLike;\n /**\n * Which connected database the journal + migrations target (key of the\n * service's db map). Defaults to the FIRST connected key — set this explicitly\n * in multi-database services to avoid silently migrating the wrong one.\n */\n db?: string;\n /**\n * Migration claim lease in ms (default 120_000). A `running` claim older than\n * the lease is considered orphaned (hard crash) and may be stolen by another\n * runner; live claims are renewed automatically during long `up()`s.\n */\n leaseMs?: number;\n}\n\n/** Matches `NNN_name.ts|js|mjs` — the numeric prefix drives ordering. */\nexport const MIGRATION_FILE = /^(\\d+)_.+\\.(ts|js|mjs)$/;\n\n/** Collection name of the migration journal (reserved `_`-prefixed name). */\nexport const JOURNAL_COLLECTION = '_migrations';\n","/**\n * Migration file discovery + loading + scaffolding (pure filesystem helpers).\n * `listMigrationFiles` orders by the numeric prefix; `loadMigration` imports a\n * file as a module; `nextMigrationNumber`/`ensureDir` support `create`.\n */\nimport { mkdir, readdir } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { MIGRATION_FILE, type MigrationModule } from './types.ts';\n\n/** Strip the `NNN_` prefix and extension → the migration's logical name. */\nexport const migrationNameOf = (file: string): string =>\n basename(file).replace(/\\.(ts|js|mjs)$/, '');\n\nconst numericPrefixOf = (file: string): number =>\n Number(MIGRATION_FILE.exec(basename(file))?.[1] ?? Number.MAX_SAFE_INTEGER);\n\n/**\n * List migration files ordered by NUMERIC prefix (then name). A plain string\n * sort would run `1000_late.ts` before `999_early.ts` and `45_x.ts` after\n * `100_y.ts` — silently reordering schema evolution.\n */\nexport const listMigrationFiles = async (dir: string): Promise<string[]> => {\n const files = await readdir(dir);\n return files\n .filter((file) => MIGRATION_FILE.test(file))\n .sort((a, b) => numericPrefixOf(a) - numericPrefixOf(b) || a.localeCompare(b));\n};\n\n/** Import a migration file as `{ up, down }` + its file-derived logical name. */\nexport const loadMigration = async (\n dir: string,\n file: string,\n): Promise<MigrationModule & { name: string }> => {\n const mod = (await import(pathToFileURL(join(dir, file)).href)) as MigrationModule;\n // The FILE decides the identity — a module-exported `name` must not override\n // it (two files with colliding module exports would merge into one journal row).\n return { ...mod, name: migrationNameOf(file) };\n};\n\n/** Ensure the migration directory exists. */\nexport const ensureMigrationDir = async (dir: string): Promise<void> => {\n await mkdir(dir, { recursive: true });\n};\n\n/** The next free numeric prefix (max existing + 1). */\nexport const nextMigrationNumber = async (dir: string): Promise<number> => {\n const files = await readdir(dir);\n return (\n files.reduce((max, file) => {\n const match = MIGRATION_FILE.exec(file);\n return match ? Math.max(max, Number(match[1])) : max;\n }, 0) + 1\n );\n};\n","import { randomUUID } from 'node:crypto';\nimport type { Document } from 'mongodb';\nimport { JOURNAL_COLLECTION, type JournalManager } from './types.ts';\n\nexport interface MigrationJournal {\n appliedNames(): Promise<Set<string>>;\n /** Returns a unique ownership token only to the runner that won the claim. */\n claim(name: string, file: string, leaseMs: number): Promise<string | null>;\n /** Claim an applied migration for rollback without allowing `up()` to rerun it. */\n claimRollback(name: string, file: string, leaseMs: number): Promise<string | null>;\n renew(name: string, claimId: string, leaseMs: number): Promise<void>;\n markApplied(name: string, claimId: string): Promise<void>;\n removeRunning(name: string, claimId: string): Promise<void>;\n unrecord(name: string, claimId: string): Promise<void>;\n}\n\nconst isDuplicateKeyError = (err: unknown): boolean => {\n const code = (err as { code?: number } | null)?.code;\n if (code === 11000 || code === 11001) return true;\n return /E11000 duplicate key/.test(String((err as Error | null)?.message ?? ''));\n};\n\nconst expiredLeaseFilter = (now: Date, staleCutoff: Date): Document => ({\n $or: [\n { expiresAt: { $lt: now } },\n { expiresAt: { $exists: false }, appliedAt: { $lt: staleCutoff } },\n ],\n});\n\n/** Build the journal operations over a `JournalManager` (a connected manager). */\nexport const createMigrationJournal = (manager: JournalManager): MigrationJournal => {\n let indexReady = false;\n const ensureIndex = async (): Promise<void> => {\n if (indexReady) return;\n // Without uniqueness, concurrent fresh claims are not safe. Real managers\n // always implement createIndex; the optional branch supports tiny test doubles.\n if (manager.createIndex) {\n await manager.createIndex(JOURNAL_COLLECTION, { name: 1 }, { unique: true });\n }\n indexReady = true;\n };\n\n const appliedNames = async (): Promise<Set<string>> => {\n const rows = await manager.findMany(JOURNAL_COLLECTION, {}, { cache: false });\n return new Set(\n rows\n .filter(\n (row) =>\n row.status === undefined || row.status === 'applied' || row.status === 'rolling_back',\n )\n .map((row) => row.name as string),\n );\n };\n\n const claim = async (name: string, file: string, leaseMs: number): Promise<string | null> => {\n await ensureIndex();\n const now = new Date();\n const staleCutoff = new Date(Date.now() - leaseMs);\n const claimId = randomUUID();\n const stole = await manager.findOneAndUpdate(\n JOURNAL_COLLECTION,\n {\n name,\n status: { $nin: ['applied', 'rolling_back'] },\n ...expiredLeaseFilter(now, staleCutoff),\n },\n {\n $set: {\n status: 'running',\n appliedAt: now,\n file,\n expiresAt: new Date(Date.now() + leaseMs),\n claimId,\n },\n },\n { returnDocument: 'before', cache: false },\n );\n if (stole !== null) return claimId;\n\n try {\n await manager.insertOne(JOURNAL_COLLECTION, {\n name,\n appliedAt: now,\n status: 'running',\n file,\n expiresAt: new Date(Date.now() + leaseMs),\n claimId,\n });\n return claimId;\n } catch (err) {\n if (isDuplicateKeyError(err)) return null;\n throw err;\n }\n };\n\n const claimRollback = async (\n name: string,\n file: string,\n leaseMs: number,\n ): Promise<string | null> => {\n await ensureIndex();\n const now = new Date();\n const claimId = randomUUID();\n const claimed = await manager.findOneAndUpdate(\n JOURNAL_COLLECTION,\n {\n name,\n $or: [\n { status: 'applied' },\n { status: 'rolling_back', ...expiredLeaseFilter(now, new Date(Date.now() - leaseMs)) },\n ],\n },\n {\n $set: {\n status: 'rolling_back',\n file,\n claimId,\n expiresAt: new Date(Date.now() + leaseMs),\n },\n },\n { returnDocument: 'before', cache: false },\n );\n return claimed === null ? null : claimId;\n };\n\n const renew = async (name: string, claimId: string, leaseMs: number): Promise<void> => {\n await manager.updateOne(\n JOURNAL_COLLECTION,\n { name, claimId, status: { $in: ['running', 'rolling_back'] } },\n { $set: { expiresAt: new Date(Date.now() + leaseMs) } },\n { cache: false },\n );\n };\n\n const markApplied = async (name: string, claimId: string): Promise<void> => {\n const res = await manager.updateOne(\n JOURNAL_COLLECTION,\n { name, claimId, status: 'running' },\n { $set: { status: 'applied' }, $unset: { expiresAt: '', claimId: '' } },\n { cache: false },\n );\n if ((res as { matchedCount?: number })?.matchedCount === 0) {\n // Restore a journal row only when no successor claimed the name. Either\n // way, report lost ownership so the operator can inspect the migration.\n await manager\n .insertOne(JOURNAL_COLLECTION, { name, appliedAt: new Date(), status: 'applied' })\n .catch(() => {});\n throw new Error(`Migration \"${name}\" lost its claim before it could be marked applied`);\n }\n };\n\n const removeRunning = async (name: string, claimId: string): Promise<void> => {\n await manager\n .deleteOne(JOURNAL_COLLECTION, { name, claimId, status: 'running' }, { cache: false })\n .catch(() => {});\n };\n\n const unrecord = async (name: string, claimId: string): Promise<void> => {\n const result = await manager.deleteOne(\n JOURNAL_COLLECTION,\n { name, claimId, status: 'rolling_back' },\n { cache: false },\n );\n if ((result as { deletedCount?: number })?.deletedCount === 0) {\n throw new Error(`Migration \"${name}\" lost its rollback claim`);\n }\n };\n\n return { appliedNames, claim, claimRollback, renew, markApplied, removeRunning, unrecord };\n};\n","/**\n * File-based migration runner — `createMongoMigrationRunner`. Orchestrates the\n * two sub-systems:\n *\n * - `./files.ts` — discover / load / scaffold `NNN_name.ts` files\n * - `./journal.ts` — lease-based `_migrations` journal (atomic, crash-safe)\n *\n * `up()` applies pending migrations in numeric order under an exclusive claim\n * with an auto-renewed, owner-fenced lease; `down()` uses the same fencing,\n * rolls back in reverse order, and validates its target BEFORE destroying\n * anything; `status()` reports applied/pending; `create()` scaffolds a new file\n * atomically (`wx` — concurrent scaffolds never clobber each other).\n */\n\nimport { writeFile } from 'node:fs/promises';\nimport { basename, join } from 'node:path';\nimport type { LoggerLike } from '../utils/logger.ts';\nimport {\n ensureMigrationDir,\n listMigrationFiles,\n loadMigration,\n migrationNameOf,\n nextMigrationNumber,\n} from './files.ts';\nimport { createMigrationJournal } from './journal.ts';\nimport type { JournalManager, MongoMigrationRunner, MongoMigrationRunnerOptions } from './types.ts';\n\n/** The `service` shape the runner needs (one connected manager + config/logger). */\ninterface MigrationService {\n db: Record<string, unknown>;\n logger: LoggerLike;\n config?: { migrationDir?: string };\n}\n\nconst DEFAULT_LEASE_MS = 120_000;\n\nexport const createMongoMigrationRunner = (\n service: MigrationService,\n options: MongoMigrationRunnerOptions = {},\n): MongoMigrationRunner => {\n const migrationDir = options.migrationDir ?? service.config?.migrationDir ?? './migrations';\n const logger = options.logger ?? service.logger;\n const leaseMs = options.leaseMs ?? DEFAULT_LEASE_MS;\n\n const manager = (): JournalManager => {\n const keys = Object.keys(service.db);\n // Explicit option first; otherwise the first connected key. In multi-DB\n // services insertion order is arbitrary — pass `db:` explicitly.\n const key = options.db !== undefined ? options.db : keys[0];\n const db = key ? (service.db[key] as JournalManager | undefined) : undefined;\n if (!db) {\n throw new Error(\n options.db !== undefined && !keys.includes(options.db)\n ? `Unknown database \"${options.db}\" — connected: ${keys.join(', ')}`\n : 'No database client connected — call service.makeConnections() first',\n );\n }\n return db;\n };\n\n /** Heartbeat that keeps a running claim's lease alive during a long operation. */\n const startHeartbeat = (\n journal: ReturnType<typeof createMigrationJournal>,\n name: string,\n claimId: string,\n ) => {\n const timer = setInterval(\n () => {\n void journal.renew(name, claimId, leaseMs).catch(() => {});\n },\n Math.max(leaseMs / 2, 1_000),\n );\n // Never hold the event loop open just for the heartbeat.\n timer.unref?.();\n return () => clearInterval(timer);\n };\n\n const up = async (): Promise<void> => {\n await ensureMigrationDir(migrationDir);\n const journal = createMigrationJournal(manager());\n\n const files = await listMigrationFiles(migrationDir);\n const applied = await journal.appliedNames();\n const pending = files.filter((file) => !applied.has(migrationNameOf(file)));\n\n for (const file of pending) {\n const migration = await loadMigration(migrationDir, file);\n logger.info({ name: migration.name }, 'running migration up');\n // Exclusive lease-based claim: fresh rows insert, expired claims steal,\n // applied/live rows reject. `status` flips to `applied` only AFTER\n // `up()` succeeds.\n const claimId = await journal.claim(migration.name, basename(file), leaseMs);\n if (claimId === null) {\n logger.info(\n { name: migration.name },\n 'migration claimed by another runner or already applied, skipping',\n );\n continue;\n }\n const stopHeartbeat = startHeartbeat(journal, migration.name, claimId);\n try {\n await migration.up({ service, logger, name: migration.name });\n await journal.markApplied(migration.name, claimId);\n } catch (err) {\n await journal.removeRunning(migration.name, claimId);\n throw err;\n } finally {\n stopHeartbeat();\n }\n logger.info({ name: migration.name }, 'migration applied');\n }\n };\n\n const down = async (targetName?: string): Promise<void> => {\n const files = await listMigrationFiles(migrationDir);\n // Validate the target BEFORE touching the DB: a typo'd name must fail\n // loudly instead of silently rolling back EVERYTHING.\n if (targetName !== undefined) {\n const known = files.some((file) => migrationNameOf(file) === targetName);\n if (!known) {\n throw new Error(\n `down(): unknown migration \"${targetName}\" — known: ${files.map(migrationNameOf).join(', ') || '(none)'}`,\n );\n }\n }\n const journal = createMigrationJournal(manager());\n const applied = await journal.appliedNames();\n const appliedFiles = files.filter((file) => applied.has(migrationNameOf(file))).reverse();\n\n for (const file of appliedFiles) {\n const migration = await loadMigration(migrationDir, file);\n const claimId = await journal.claimRollback(migration.name, basename(file), leaseMs);\n if (claimId === null) {\n logger.info({ name: migration.name }, 'migration rollback already claimed, skipping');\n continue;\n }\n const stopHeartbeat = startHeartbeat(journal, migration.name, claimId);\n logger.info({ name: migration.name }, 'running migration down');\n try {\n await migration.down({ service, logger, name: migration.name });\n await journal.unrecord(migration.name, claimId);\n } finally {\n stopHeartbeat();\n }\n logger.info({ name: migration.name }, 'migration rolled back');\n if (targetName !== undefined && migration.name === targetName) break;\n }\n };\n\n const status = async (): Promise<{ applied: string[]; pending: string[] }> => {\n const files = await listMigrationFiles(migrationDir);\n const applied = await createMigrationJournal(manager()).appliedNames();\n const all = files.map(migrationNameOf);\n return {\n applied: all.filter((name) => applied.has(name)),\n pending: all.filter((name) => !applied.has(name)),\n };\n };\n\n const create = async (name: string): Promise<string> => {\n await ensureMigrationDir(migrationDir);\n const template = `import type { MigrationContext } from '@ignex/ninox';\n\nexport const up = async (ctx: MigrationContext): Promise<void> => {\n // const users = ctx.service.db.primaryClient;\n // await users.createSchema('users');\n};\n\nexport const down = async (ctx: MigrationContext): Promise<void> => {\n // const users = ctx.service.db.primaryClient;\n // await users.client.dropCollection('users');\n};\n`;\n // Atomic scaffold: `wx` fails if the file appeared between our number\n // scan and the write (concurrent `create()` calls), so we bump + retry\n // instead of silently overwriting someone else's migration.\n for (;;) {\n const next = await nextMigrationNumber(migrationDir);\n const padded = String(next).padStart(3, '0');\n const fileName = `${padded}_${name}.ts`;\n const filePath = join(migrationDir, fileName);\n try {\n await writeFile(filePath, template, { encoding: 'utf8', flag: 'wx' });\n logger.info({ name, file: fileName }, 'migration scaffolded');\n return filePath;\n } catch (err) {\n if ((err as NodeJS.ErrnoException)?.code === 'EEXIST') continue;\n throw err;\n }\n }\n };\n\n return { up, down, status, create };\n};\n\n// Re-export the public migration types so the folder barrel matches the old\n// single-module exports.\nexport type {\n MigrationContext,\n MigrationModule,\n MongoMigrationRunner,\n MongoMigrationRunnerOptions,\n} from './types.ts';\n","import type { ClientSession, MongoClient } from 'mongodb';\nimport { isMongoTransientError } from './errors/index.ts';\nimport type { LoggerLike } from './utils/logger.ts';\nimport { sleep } from './utils/timeout.ts';\n\nexport { isMongoTransientError, TRANSIENT_MONGO_ERROR_CODES } from './errors/index.ts';\n\nexport interface RetryOptions {\n maxAttempts?: number;\n delayMs?: number;\n logger?: LoggerLike;\n}\n\n/**\n * Retry `fn` while it throws a *transient* Mongo error (network / not-primary /\n * sharding / server-selection during failover), with exponential backoff\n * `delayMs * 2^attempt` plus ±20% jitter — synchronized retry waves against a\n * recovering cluster amplify outages instead of absorbing them. Domain errors\n * and genuine data errors are never retried.\n */\nexport const withRetry = async <T>(\n fn: () => Promise<T>,\n options: RetryOptions = {},\n): Promise<T> => {\n const maxAttempts = Math.max(1, options.maxAttempts ?? 3);\n const delayMs = options.delayMs ?? 150;\n const logger = options.logger;\n\n let attempt = 0;\n let lastError: unknown;\n while (attempt < maxAttempts) {\n try {\n return await fn();\n } catch (err) {\n lastError = err;\n attempt += 1;\n if (attempt >= maxAttempts || !isMongoTransientError(err)) throw err;\n const base = delayMs * 2 ** (attempt - 1);\n // ±20% jitter around the exponential backoff.\n const backoff = Math.round(base * (0.8 + Math.random() * 0.4));\n logger?.debug?.({ attempt, backoffMs: backoff, error: (err as Error)?.message }, 'retrying');\n await sleep(backoff);\n }\n }\n // The loop above runs at least once and either returns or throws, so this is\n // unreachable in practice — but it guarantees `maxAttempts: 0` never turns\n // into `throw undefined`.\n throw lastError ?? new Error('withRetry: no attempt was made (maxAttempts must be >= 1)');\n};\n\n/**\n * Manual transaction helper: start → run → commit, aborting + ending the\n * session on any failure. Prefer the service-level `transaction()` which also\n * handles capability detection and unsupported-server fallback.\n */\nexport const withTransaction = async <T>(\n client: MongoClient,\n fn: (session: ClientSession) => Promise<T>,\n): Promise<T> => {\n const session = client.startSession();\n try {\n session.startTransaction();\n const result = await fn(session);\n await session.commitTransaction();\n return result;\n } catch (err) {\n await session.abortTransaction().catch(() => {});\n throw err;\n } finally {\n // Never let a failing `endSession` mask the original error.\n await session.endSession().catch(() => {});\n }\n};\n","/** Default cap for list/pagination limits (mirrors sdk-db). */\nexport const DEFAULT_MAX_LIMIT = 1000;\n\n/** Default limit applied to `findMany` when none is provided. */\nexport const DEFAULT_FIND_LIMIT = 100;\n\n/**\n * Hard cap for a single `insertMany` / `bulkWrite` / `bulkUpsert` call (the\n * driver splits at 100k; anything above is almost certainly an unbounded caller\n * array). Above this the ORM throws `BadRequest` instead of spiking memory.\n */\nexport const MAX_BATCH_OPS = 100_000;\n","import type {\n Collection,\n Document,\n Filter,\n FindCursor,\n FindOptions,\n Hint,\n Sort,\n WithId,\n} from 'mongodb';\nimport { BadRequest } from '../errors/index.ts';\nimport type { QueryOptions } from '../service/query-options.ts';\nimport { DEFAULT_FIND_LIMIT } from '../shared/constants.ts';\nimport type { FilterInput } from '../shared/filter-types.ts';\n\n/**\n * Execution context provided by the CRUD layer. `run` participates in the\n * uniform trace + retry + cache + in-flight-dedup pipeline and returns the\n * merged driver options to the execute closure.\n */\nexport interface QueryBuilderContext<TDoc extends Document> {\n physicalName: string;\n collection: Collection<TDoc>;\n run: <T>(\n opName: string,\n filter: FilterInput<TDoc>,\n execute: (driverOpts: FindOptions) => Promise<T>,\n options?: QueryOptions,\n ) => Promise<T>;\n}\n\n/**\n * Merge an incoming filter into the current one WITHOUT silently dropping\n * clauses: plain-object values are treated as operator documents\n * (`{ $gte: 18 }`) and deep-merged per key so\n * `.where({ age: { $gte: 18 } }).where({ age: { $lte: 65 } })`\n * yields `{ age: { $gte: 18, $lte: 65 } }` instead of losing the `$gte`.\n * Scalars/arrays replace (last write wins), matching Mongo semantics.\n */\nconst mergeFilterKey = (prev: unknown, next: unknown): unknown => {\n if (\n prev !== null &&\n typeof prev === 'object' &&\n !Array.isArray(prev) &&\n next !== null &&\n typeof next === 'object' &&\n !Array.isArray(next)\n ) {\n return { ...(prev as Document), ...(next as Document) };\n }\n return next;\n};\n\n/**\n * Lazy, fluent, IMMUTABLE, schema-typed query builder. Every chain method\n * returns a NEW builder — a stored base query can be safely reused as a\n * template without derived chains contaminating it:\n *\n * const admins = users.query('users').where({ role: 'admin' });\n * await admins.where({ age: { $gte: 18 } }).many(); // base unchanged\n *\n * Nothing hits the database until an executor (`one`/`many`/`cursor`/`count`/\n * `exists`) is called. Projections via `select` are pushed to the driver so\n * only requested fields are transferred.\n */\nexport class QueryBuilder<TDoc extends Document, TSelection = TDoc> {\n private _filter: FilterInput<TDoc> = {};\n private _sort?: Sort;\n private _skip?: number;\n private _limit?: number;\n private _projection?: Document;\n private _options: QueryOptions = {};\n\n constructor(private readonly ctx: QueryBuilderContext<TDoc>) {}\n\n get filter(): FilterInput<TDoc> {\n return this._filter;\n }\n\n /** Copy-on-write fork used by every chain method. */\n private fork(): QueryBuilder<TDoc, TSelection> {\n const next = new QueryBuilder<TDoc, TSelection>(this.ctx);\n next._filter = this._filter;\n if (this._sort !== undefined) next._sort = this._sort;\n if (this._skip !== undefined) next._skip = this._skip;\n if (this._limit !== undefined) next._limit = this._limit;\n if (this._projection !== undefined) next._projection = this._projection;\n next._options = { ...this._options };\n return next;\n }\n\n /** Merge a filter into the current one (operator docs deep-merge per key). */\n where(filter: FilterInput<TDoc>): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n const merged: Document = { ...(next._filter as Document) };\n for (const [key, value] of Object.entries(filter as Document)) {\n merged[key] = key in merged ? mergeFilterKey(merged[key], value) : value;\n }\n next._filter = merged as FilterInput<TDoc>;\n return next;\n }\n\n /** AND-combine the current filter with a new one (stays flat across repeats). */\n and(filter: FilterInput<TDoc>): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n const current = next._filter as Document;\n const existing = Array.isArray(current.$and)\n ? (current.$and as Document[])\n : Object.keys(current).length > 0\n ? [current]\n : [];\n next._filter = { $and: [...existing, filter] } as unknown as FilterInput<TDoc>;\n return next;\n }\n\n /**\n * OR-combine: current filter AND (filter1 OR filter2 ...). Requires at least\n * one filter — an empty `$or` is rejected by the server.\n */\n or(...filters: Array<FilterInput<TDoc>>): QueryBuilder<TDoc, TSelection> {\n if (filters.length === 0) {\n throw new BadRequest('QueryBuilder.or() requires at least one filter');\n }\n return this.and((filters.length === 1 ? filters[0]! : { $or: filters }) as FilterInput<TDoc>);\n }\n\n /** Set the sort order (`{ field: 1 | -1 }`). */\n sort(sort: Sort): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._sort = sort;\n return next;\n }\n\n /** Skip the first `n` matching documents. */\n skip(n: number): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._skip = n;\n return next;\n }\n\n /** Limit the result set to `n` documents. */\n limit(n: number): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._limit = n;\n return next;\n }\n\n /** Project only the given fields — the projection is pushed to the driver. */\n select<const K extends keyof TSelection>(\n fields: readonly K[],\n ): QueryBuilder<TDoc, Pick<TSelection, K>> {\n const next = this.fork() as unknown as QueryBuilder<TDoc, Pick<TSelection, K>>;\n const projection: Record<string, 1> = {};\n for (const field of fields) projection[field as string] = 1;\n (next as unknown as { _projection?: Document })._projection = projection;\n return next;\n }\n\n /** Raw projection document (`{ field: 1 }` / `{ field: 0 }`). */\n project(projection: Document): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._projection = projection;\n return next;\n }\n\n /** Set the index hint. */\n hint(hint: Hint): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.hint = hint;\n return next;\n }\n\n /** Set the driver cursor batch size. */\n batchSize(n: number): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.batchSize = n;\n return next;\n }\n\n /** Run the query inside a transaction session. */\n session(session: NonNullable<QueryOptions['session']>): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.session = session;\n return next;\n }\n\n /** Cap server-side execution time. */\n maxTimeMS(ms: number): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.maxTimeMS = ms;\n return next;\n }\n\n /** Bypass the read cache for this query when `false`. */\n cache(on: boolean): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.cache = on;\n return next;\n }\n\n /** Override in-flight dedup for this query when set. */\n dedupe(on: boolean): QueryBuilder<TDoc, TSelection> {\n const next = this.fork();\n next._options.dedupe = on;\n return next;\n }\n\n /** Compile the builder into driver options (does not execute). */\n private compile(): FindOptions & QueryOptions {\n const out: FindOptions & QueryOptions = { ...this._options };\n if (this._sort) out.sort = this._sort;\n if (this._skip !== undefined) out.skip = this._skip;\n if (this._limit !== undefined) out.limit = this._limit;\n if (this._projection) out.projection = this._projection;\n return out;\n }\n\n private countOptions(): FindOptions & QueryOptions {\n // countDocuments accepts skip/limit/session/hint/maxTimeMS but NOT sort/projection.\n const out: FindOptions & QueryOptions = { ...this._options };\n if (this._skip !== undefined) out.skip = this._skip;\n if (this._limit !== undefined) out.limit = this._limit;\n return out;\n }\n\n /** Fetch one document (limit forced to 1). */\n async one(): Promise<WithId<TSelection> | null> {\n const options = this.compile();\n if (options.limit === undefined) options.limit = 1;\n return this.ctx.run<WithId<TSelection> | null>(\n 'mongo.getOne',\n this._filter,\n (opts) =>\n this.ctx.collection.findOne(\n this._filter as unknown as Filter<TDoc>,\n opts,\n ) as unknown as Promise<WithId<TSelection> | null>,\n options,\n );\n }\n\n /** Fetch many documents (default limit 100 when unset). */\n async many(): Promise<WithId<TSelection>[]> {\n const options = this.compile();\n if (options.limit === undefined) options.limit = DEFAULT_FIND_LIMIT;\n return this.ctx.run<WithId<TSelection>[]>(\n 'mongo.findMany',\n this._filter,\n (opts) =>\n this.ctx.collection\n .find(this._filter as unknown as Filter<TDoc>, opts)\n .toArray() as unknown as Promise<WithId<TSelection>[]>,\n options,\n );\n }\n\n /** Streaming cursor (raw driver cursor; no retry/cache/drift — caller-owned). */\n cursor(): FindCursor<WithId<TDoc>> {\n return this.ctx.collection.find(\n this._filter as unknown as Filter<TDoc>,\n this.compile() as FindOptions,\n );\n }\n\n /** Count matching documents. */\n async count(): Promise<number> {\n return this.ctx.run(\n 'mongo.countDocuments',\n this._filter,\n (opts) => this.ctx.collection.countDocuments(this._filter as unknown as Filter<TDoc>, opts),\n this.countOptions() as QueryOptions,\n );\n }\n\n /** True when at least one document matches (`_id`-only projection — no doc transfer). */\n async exists(): Promise<boolean> {\n const options = this.compile();\n if (options.limit === undefined) options.limit = 1;\n options.projection = { _id: 1 };\n const doc = await this.ctx.run<WithId<TDoc> | null>(\n 'mongo.exists',\n this._filter,\n (opts) =>\n this.ctx.collection.findOne(\n this._filter as unknown as Filter<TDoc>,\n opts,\n ) as unknown as Promise<WithId<TDoc> | null>,\n options,\n );\n return doc !== null;\n }\n}\n","/**\n * Relation definitions used by `populate`. Relations declare how documents in\n * one collection reference documents in another; `populate` then resolves them\n * with DataLoader-batched `$in` queries (1 + N queries total, not 1 + N×M).\n */\nimport type { Document } from 'mongodb';\nimport type { RemoveIndexSignature } from '../shared/types.ts';\nimport type {\n DbClientsDefinition,\n ExtractCollectionNames,\n ExtractCollectionType,\n ExtractDbNames,\n} from '../types.ts';\n\nexport interface RelationDefBase {\n /** Foreign logical collection. */\n collection: string;\n /** Field on the source document holding the reference key(s). */\n localField: string;\n /** Field on the foreign document to match (default `_id`). */\n foreignField?: string;\n /** Field name attached to the source document after population. */\n as: string;\n /** Optional: max keys per batched `$in` query. */\n maxBatchSize?: number;\n /** Optional: cache resolved relations on the loader (default true). */\n cache?: boolean;\n /** When true, a missing belongsTo target attaches `undefined` instead of `null`. */\n optional?: boolean;\n}\n\nexport interface BelongsToRelation extends RelationDefBase {\n type: 'belongsTo';\n}\n\nexport interface HasManyRelation extends RelationDefBase {\n type: 'hasMany';\n}\n\nexport interface ManyToManyRelation extends RelationDefBase {\n type: 'manyToMany';\n through: {\n /** Join collection (logical). */\n collection: string;\n /** Field on the join doc pointing at the source doc. */\n localField: string;\n /** Field on the join doc pointing at the target doc. */\n foreignField: string;\n };\n}\n\nexport type RelationDef = BelongsToRelation | HasManyRelation | ManyToManyRelation;\n\n/* ------------------------------------------------------------------ *\n * Schema-validated relation types. `populate` constrains each relation\n * against the schema registry: `collection` must be a known collection,\n * `localField` a field on the source doc, `foreignField` a field on the\n * target doc, and `through.*` fields on the join doc.\n * ------------------------------------------------------------------ */\n\ntype RelColNames<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> = ExtractCollectionNames<TClients, TDb>;\n\ntype RelDocOf<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n C extends RelColNames<TClients, TDb>,\n> = ExtractCollectionType<TClients, TDb, C>;\n\n/** Field-name union of a doc, excluding Mongo `Document`'s index-signature keys. */\ntype RelField<T> = Extract<keyof RemoveIndexSignature<T>, string>;\n\n/** Validates one relation object `R` against the source doc and the registry. */\nexport type ValidRelation<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n TSource extends Document,\n R,\n> = R extends { type: 'belongsTo'; collection: infer C }\n ? C extends RelColNames<TClients, TDb>\n ? Omit<R, 'localField' | 'foreignField'> & {\n localField: RelField<TSource>;\n foreignField?: RelField<RelDocOf<TClients, TDb, C>>;\n }\n : never\n : R extends { type: 'hasMany'; collection: infer C }\n ? C extends RelColNames<TClients, TDb>\n ? Omit<R, 'localField' | 'foreignField'> & {\n localField: RelField<TSource>;\n foreignField?: RelField<RelDocOf<TClients, TDb, C>>;\n }\n : never\n : R extends {\n type: 'manyToMany';\n collection: infer C;\n through: { collection: infer TC };\n }\n ? C extends RelColNames<TClients, TDb>\n ? TC extends RelColNames<TClients, TDb>\n ? Omit<R, 'localField' | 'foreignField' | 'through'> & {\n localField: RelField<TSource>;\n foreignField?: RelField<RelDocOf<TClients, TDb, C>>;\n through: {\n collection: TC;\n localField: RelField<RelDocOf<TClients, TDb, TC>>;\n foreignField: RelField<RelDocOf<TClients, TDb, TC>>;\n };\n }\n : never\n : never\n : never;\n\n/**\n * Maps a tuple of relations to the joined `as` fields attached to result docs.\n * `belongsTo` resolves to `Doc | null`; `hasMany` / `manyToMany` to `Doc[]`.\n */\nexport type JoinedFields<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n R extends readonly unknown[],\n> = {\n [K in keyof R as K extends `${number}`\n ? R[K] extends { as: infer A extends string }\n ? A\n : never\n : never]: R[K] extends { type: 'belongsTo'; collection: infer C }\n ? C extends RelColNames<TClients, TDb>\n ? RelDocOf<TClients, TDb, C> | null\n : never\n : R[K] extends { type: 'hasMany' | 'manyToMany'; collection: infer C }\n ? C extends RelColNames<TClients, TDb>\n ? RelDocOf<TClients, TDb, C>[]\n : never\n : never;\n};\n\ntype BelongsToConfig<C extends string, A extends string, L extends string, F extends string> = Omit<\n BelongsToRelation,\n 'type' | 'collection' | 'as' | 'localField' | 'foreignField'\n> & {\n collection: C;\n as: A;\n localField: L;\n foreignField?: F;\n};\n\ntype HasManyConfig<C extends string, A extends string, L extends string, F extends string> = Omit<\n HasManyRelation,\n 'type' | 'collection' | 'as' | 'localField' | 'foreignField'\n> & {\n collection: C;\n as: A;\n localField: L;\n foreignField?: F;\n};\n\ntype ManyToManyConfig<\n C extends string,\n A extends string,\n L extends string,\n TC extends string,\n F extends string,\n TLoc extends string,\n TFor extends string,\n> = Omit<\n ManyToManyRelation,\n 'type' | 'collection' | 'as' | 'localField' | 'foreignField' | 'through'\n> & {\n collection: C;\n as: A;\n localField: L;\n foreignField?: F;\n through: {\n collection: TC;\n localField: TLoc;\n foreignField: TFor;\n };\n};\n\n/** One source doc → at most one foreign doc (defaults `foreignField: '_id'`). */\nexport const belongsTo = <\n const C extends string,\n const A extends string,\n const L extends string,\n const F extends string = '_id',\n>(\n config: BelongsToConfig<C, A, L, F>,\n): BelongsToRelation & { collection: C; as: A; localField: L; foreignField: F } =>\n ({\n type: 'belongsTo',\n foreignField: '_id',\n ...config,\n }) as BelongsToRelation & { collection: C; as: A; localField: L; foreignField: F };\n\n/** One source doc → many foreign docs (defaults `foreignField: '_id'`). */\nexport const hasMany = <\n const C extends string,\n const A extends string,\n const L extends string,\n const F extends string = '_id',\n>(\n config: HasManyConfig<C, A, L, F>,\n): HasManyRelation & { collection: C; as: A; localField: L; foreignField: F } =>\n ({\n type: 'hasMany',\n foreignField: '_id',\n ...config,\n }) as HasManyRelation & { collection: C; as: A; localField: L; foreignField: F };\n\n/** Source doc → join docs → target docs through a pivot collection. */\nexport const manyToMany = <\n const C extends string,\n const A extends string,\n const L extends string,\n const TC extends string,\n const F extends string = '_id',\n const TLoc extends string = '_id',\n const TFor extends string = '_id',\n>(\n config: ManyToManyConfig<C, A, L, TC, F, TLoc, TFor>,\n): ManyToManyRelation & {\n collection: C;\n as: A;\n localField: L;\n foreignField: F;\n through: { collection: TC; localField: TLoc; foreignField: TFor };\n} =>\n ({\n type: 'manyToMany',\n foreignField: '_id',\n ...config,\n }) as ManyToManyRelation & {\n collection: C;\n as: A;\n localField: L;\n foreignField: F;\n through: { collection: TC; localField: TLoc; foreignField: TFor };\n };\n","/**\n * Optional repository layer over a `CollectionManager` — a thin, domain-typed\n * convenience wrapper. The op-based core API is unchanged; a repository just\n * binds a manager + collection name so call sites don't repeat the collection\n * literal, and adds small ergonomic helpers (`getById`, `getByIds`,\n * `updateVersioned`, `exists`, …).\n *\n * There is deliberately NO change tracking / unit-of-work: `getById` → mutate →\n * `update`/`updateVersioned` is explicit, matching the core op semantics. All\n * perf features (cache, dedup, batching, populate) and collection hooks /\n * timestamps apply transparently because every method delegates to the manager.\n */\nimport type {\n AggregationCursor,\n ChangeStream,\n ChangeStreamOptions,\n DeleteResult,\n Document,\n FindOneAndUpdateOptions,\n InsertManyResult,\n InsertOneOptions,\n InsertOneResult,\n UpdateOptions,\n UpdateResult,\n} from 'mongodb';\nimport type { PopulateOptions } from '../relation/populate.ts';\nimport type { JoinedFields, RelationDef, ValidRelation } from '../relation/relation.ts';\nimport type { AggregationStages } from '../service/aggregation-stages.ts';\nimport type {\n FindQueryOptions,\n InsertInput,\n VersionedUpdateResult,\n} from '../service/crud/index.ts';\nimport type { CollectionManager } from '../service/index.ts';\nimport type {\n CursorPage,\n CursorPaginationConfig,\n PaginationConfig,\n} from '../service/pagination/index.ts';\nimport type { PipelineBuilder } from '../service/pipeline-builder.ts';\nimport type { QueryOptions } from '../service/query-options.ts';\nimport type { UpdateInput } from '../service/update-types.ts';\nimport type { FilterInput } from '../shared/filter-types.ts';\nimport type { PaginationResult } from '../shared/pagination-result.ts';\nimport type {\n DbClientsDefinition,\n ExtractCollectionNames,\n ExtractCollectionType,\n ExtractDbNames,\n} from '../types.ts';\n\nexport interface RepositoryOptions {\n /** Default `findMany` limit (defaults to the ORM's `DEFAULT_FIND_LIMIT`). */\n limit?: number;\n}\n\n/** Repository for one collection — type is derived from the manager + name. */\nexport type Repository<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n C extends ExtractCollectionNames<TClients, TDb>,\n> = RepositoryFor<TClients, TDb, C, ExtractCollectionType<TClients, TDb, C>>;\n\ntype RepositoryFor<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n C extends ExtractCollectionNames<TClients, TDb>,\n Doc extends Document,\n> = {\n readonly collection: C;\n /** The underlying manager — escape hatch to any op. */\n readonly manager: CollectionManager<TClients, TDb>;\n\n /* reads */\n /** Fetch one doc by primary key, or `null`. */\n getById(id: Doc['_id'], options?: FindQueryOptions<Doc>): Promise<Doc | null>;\n /** Fetch many docs by primary key (`$in`). */\n getByIds(ids: readonly Doc['_id'][], options?: FindQueryOptions<Doc>): Promise<Doc[]>;\n /** Fetch one doc by filter, or `null`. */\n findOne(filter?: FilterInput<Doc>, options?: FindQueryOptions<Doc>): Promise<Doc | null>;\n /** Fetch one doc by filter or throw `NOT_FOUND`. */\n findOneOrFail(filter?: FilterInput<Doc>, options?: FindQueryOptions<Doc>): Promise<Doc>;\n /** Fetch many docs (default limit from `RepositoryOptions.limit`). */\n findMany(filter?: FilterInput<Doc>, options?: FindQueryOptions<Doc>): Promise<Doc[]>;\n /** Fetch many non-soft-deleted docs. */\n findActive(filter?: FilterInput<Doc>, options?: FindQueryOptions<Doc>): Promise<Doc[]>;\n /** Count docs matching a filter. */\n count(filter?: FilterInput<Doc>, options?: QueryOptions): Promise<number>;\n /** Whether at least one doc matches. */\n exists(filter?: FilterInput<Doc>, options?: FindQueryOptions<Doc>): Promise<boolean>;\n /** Distinct values of `field`. */\n distinct<K extends keyof Doc>(\n field: K,\n filter?: FilterInput<Doc>,\n options?: FindQueryOptions<Doc>,\n ): Promise<Array<Doc[K]>>;\n\n /* writes */\n /** Insert one doc. */\n create(\n doc: InsertInput<Doc>,\n options?: InsertOneOptions & QueryOptions,\n ): Promise<InsertOneResult<Doc>>;\n /** Insert many docs. */\n createMany(\n docs: readonly InsertInput<Doc>[],\n options?: QueryOptions,\n ): Promise<InsertManyResult<Doc>>;\n /** Update one doc by primary key. */\n update(\n id: Doc['_id'],\n patch: UpdateInput<Doc>,\n options?: UpdateOptions & QueryOptions,\n ): Promise<UpdateResult<Doc>>;\n /** Optimistic-lock update by primary key (`__v` CAS). */\n updateVersioned(\n id: Doc['_id'],\n patch: UpdateInput<Doc>,\n options?: FindOneAndUpdateOptions & QueryOptions,\n ): Promise<VersionedUpdateResult<Doc>>;\n /** Delete one doc by primary key. */\n deleteById(id: Doc['_id'], options?: QueryOptions): Promise<DeleteResult>;\n /** Soft-delete one doc by primary key (sets `deletedAt`). */\n softDelete(id: Doc['_id'], options?: QueryOptions): Promise<UpdateResult<Doc>>;\n\n /* pagination */\n /** `$facet` pagination with totals (one round trip). */\n page(filter: FilterInput<Doc>, config?: PaginationConfig): Promise<PaginationResult<Doc>>;\n /** Keyset/cursor pagination (O(log n), no totals). */\n pageCursor(filter: FilterInput<Doc>, config: CursorPaginationConfig): Promise<CursorPage<Doc>>;\n\n /* aggregation */\n /** Type-safe chained aggregation builder. */\n pipeline(options?: QueryOptions): PipelineBuilder<TClients, TDb, Doc>;\n /** Callback aggregation over a typed stage builder. */\n aggregate(\n stages: (s: AggregationStages<Doc, TClients, TDb>) => Document[],\n options?: QueryOptions,\n ): Promise<AggregationCursor<Document>>;\n\n /* relations */\n /** DataLoader-batched relation population (no N+1). */\n populate<const T extends Document, const R extends readonly RelationDef[]>(\n docs: T[],\n relations: R & { [K in keyof R]: ValidRelation<TClients, TDb, T, R[K]> },\n options?: PopulateOptions,\n ): Promise<Array<T & JoinedFields<TClients, TDb, R>>>;\n\n /* realtime */\n /** Change stream (caller-owned — attach `error` listener + close). */\n watch(pipeline?: Document[], options?: ChangeStreamOptions): ChangeStream<Doc>;\n};\n\n/**\n * Bind a repository to a manager + collection. `Doc` is inferred from the\n * collection name — no `<TDoc>` at call sites.\n */\nexport const createRepository = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n C extends ExtractCollectionNames<TClients, TDb>,\n>(\n manager: CollectionManager<TClients, TDb>,\n collection: C,\n options: RepositoryOptions = {},\n): Repository<TClients, TDb, C> => {\n const repo: Repository<TClients, TDb, C> = {\n collection,\n manager,\n\n getById: (id, o) => manager.getOne(collection, { _id: id }, o),\n getByIds: (ids, o) => manager.findMany(collection, { _id: { $in: ids } }, o),\n findOne: (filter, o) => manager.getOne(collection, filter, o),\n findOneOrFail: (filter, o) => manager.getOneOrFail(collection, filter, o),\n findMany: (filter, o) =>\n manager.findMany(collection, filter, {\n // Repository `limit` is a DEFAULT — a per-call option must win.\n ...(options.limit !== undefined ? { limit: options.limit } : {}),\n ...(o ?? {}),\n }),\n findActive: (filter, o) => manager.findActive(collection, filter, o),\n count: (filter, o) => manager.countDocuments(collection, filter, o),\n exists: async (filter, o) =>\n (await manager.getOne(collection, filter, { ...(o ?? {}), projection: { _id: 1 } })) !== null,\n distinct: (field, filter, o) => manager.distinct(collection, field, filter, o),\n\n create: (doc, o) => manager.insertOne(collection, doc, o),\n createMany: (docs, o) => manager.insertMany(collection, docs, o),\n update: (id, patch, o) => manager.updateOne(collection, { _id: id }, patch, o),\n updateVersioned: (id, patch, o) => manager.updateWithVersion(collection, { _id: id }, patch, o),\n deleteById: (id, o) => manager.deleteOne(collection, { _id: id }, o),\n softDelete: (id, o) => manager.softDeleteOne(collection, { _id: id }, o),\n\n page: (filter, config) => manager.paginateFlexible(collection, filter, config),\n pageCursor: (filter, config) => manager.paginateCursor(collection, filter, config),\n\n pipeline: (o) => manager.pipeline(collection, o),\n aggregate: (stages, o) => manager.aggregate(collection, stages, o),\n\n // The repository's public signature already validates `relations` at the\n // call site; the manager's mapped-type param can't be re-inferred here\n // (TS mapped-type inference friction), so delegate through the validated\n // shape without weakening the public type.\n populate: (docs, relations, o) => manager.populate(docs, relations as never, o),\n\n watch: (pipeline, options) => manager.watchCollection(collection, pipeline, options),\n };\n return repo;\n};\n","/**\n * Schema-driven collection registry.\n *\n * Collection names are carried by the schema itself (`s.object({...}, { name })`\n * or `defineCollection(name, schema, extras)`), so the ORM's `collections` map\n * is *derived* from the schemas instead of hand-typed. The keys of the derived\n * map ARE the schema names — a typo'd collection name becomes a type error\n * everywhere (CRUD, query builder, relations, populate).\n *\n * const users = s.object(\n * { _id: s.objectId(), email: s.string() },\n * { name: 'users' },\n * );\n * const orders = defineCollection('orders', s.object({ ... }), {\n * indexes: [{ key: { userId: 1 } }],\n * });\n *\n * const dbClients = {\n * primary: {\n * name: 'app',\n * collections: defineCollections(users, orders),\n * },\n * };\n */\n\nimport type { HookMap } from '../hooks/hooks.ts';\nimport type {\n CollectionDefinition,\n CollectionLike,\n CollectionTimestamps,\n IndexSpec,\n} from '../types.ts';\nimport type { InferDoc } from './infer.ts';\nimport type { ObjectField, SchemaType } from './types.ts';\n\n/** An object schema that carries its collection name. */\nexport type NamedObjectField<N extends string = string> = ObjectField<\n Record<string, SchemaType>,\n N\n> & {\n name: N;\n};\n\n/** A collection definition (schema + optional indexes/hooks) that carries its name. */\nexport type NamedCollectionDefinition<\n N extends string = string,\n S extends ObjectField = ObjectField,\n> = CollectionDefinition<S & { name: N }> & { name: N };\n\n/** Either form accepted by `defineCollections`. */\nexport type NamedCollection =\n | (ObjectField & { name: string })\n | ({\n schema: ObjectField;\n indexes?: IndexSpec[];\n hooks?: HookMap<any>;\n timestamps?: CollectionTimestamps | boolean;\n } & { name: string });\n\n/** Extract the carried collection name from a named collection item. */\ntype StringName<T> = T extends { name: infer N } ? Extract<N, string> : never;\n\nexport type CollectionName<T> = T extends { schema: infer S } ? StringName<S> : StringName<T>;\n\n/** The value placed in the derived `collections` map for a given item. */\nexport type CollectionValue<T> = T extends {\n schema: infer S;\n indexes?: infer _Ix;\n hooks?: infer _Hk;\n}\n ? CollectionDefinition<Extract<S, ObjectField>>\n : T;\n\n/** The derived `collections` map type: keyed by each item's carried name. */\nexport type CollectionMap<T extends readonly NamedCollection[]> = {\n [K in T[number] as CollectionName<K>]: CollectionValue<K>;\n};\n\nconst resolveItemName = (item: NamedCollection): string =>\n 'schema' in item\n ? ((item as NamedCollectionDefinition).schema as NamedObjectField).name\n : (item as NamedObjectField).name;\n\n/**\n * Fail fast when `timestamps: true | {...}` names fields the schema does not\n * declare. Under strict validation (`additionalProperties: false`, the\n * default) an undeclared timestamp field gets EVERY insert/update rejected\n * server-side with an opaque `DocumentValidationFailure` — far from this\n * misconfiguration site. Throwing here turns that into a one-line fix.\n */\nconst assertTimestampsDeclared = (\n name: string,\n schema: ObjectField,\n timestamps: CollectionTimestamps | boolean,\n): void => {\n const ts = typeof timestamps === 'boolean' ? {} : timestamps;\n const createdAt = ts.createdAt ?? 'createdAt';\n const updatedAt = ts.updatedAt ?? 'updatedAt';\n const properties = schema.properties ?? {};\n for (const field of [createdAt, updatedAt]) {\n if (!(field in properties)) {\n throw new Error(\n `defineCollections: \"${name}\" enables timestamps but its schema does not declare the ` +\n `field \"${field}\". Add \\`${field}: s.date().optional()\\` to the schema (or adjust ` +\n `\\`timestamps\\`) — otherwise strict validation rejects every stamped write.`,\n );\n }\n }\n};\n\nconst resolveItemValue = (item: NamedCollection): CollectionLike => {\n if ('schema' in item) {\n const def = item as NamedCollectionDefinition;\n if (def.timestamps !== undefined) {\n assertTimestampsDeclared(def.name, def.schema, def.timestamps);\n }\n return {\n schema: def.schema,\n ...(def.indexes ? { indexes: def.indexes } : {}),\n ...(def.hooks ? { hooks: def.hooks } : {}),\n ...(def.timestamps !== undefined ? { timestamps: def.timestamps } : {}),\n };\n }\n return item as NamedObjectField;\n};\n\n/**\n * Attach a collection name to a schema (plus optional indexes/hooks) and return\n * a `CollectionDefinition`-shaped item. When no extras are needed this is\n * equivalent to `s.object({...}, { name })`.\n */\nexport const defineCollection = <N extends string, S extends ObjectField>(\n name: N,\n schema: S,\n extras: {\n indexes?: IndexSpec[];\n hooks?: HookMap<InferDoc<S>>;\n timestamps?: CollectionTimestamps | boolean;\n } = {},\n): NamedCollectionDefinition<N, S> => {\n const namedSchema = { ...(schema as object), name } as S & { name: N };\n if (extras.timestamps !== undefined) {\n assertTimestampsDeclared(name, schema, extras.timestamps);\n }\n return {\n name,\n schema: namedSchema,\n ...(extras.indexes ? { indexes: extras.indexes } : {}),\n ...(extras.hooks ? { hooks: extras.hooks } : {}),\n ...(extras.timestamps !== undefined ? { timestamps: extras.timestamps } : {}),\n } as NamedCollectionDefinition<N, S>;\n};\n\n/**\n * Derive a `collections` map from schemas that carry their own names. Throws on\n * duplicate names. The returned map's keys are the schema names and its values\n * are valid `CollectionLike` entries, so it plugs directly into\n * `DBClientDefinition.collections` with full type inference.\n */\nexport const defineCollections = <const T extends readonly NamedCollection[]>(\n ...items: T\n): CollectionMap<T> => {\n const out: Record<string, unknown> = {};\n for (const item of items) {\n const name = resolveItemName(item);\n if (name in out) {\n throw new Error(`defineCollections: duplicate collection name \"${name}\"`);\n }\n out[name] = resolveItemValue(item);\n }\n return out as CollectionMap<T>;\n};\n","import type { MongoJsonSchema } from './json-schema.ts';\nimport type { ObjectField, SchemaType } from './types.ts';\n\nexport type { MongoJsonSchema } from './json-schema.ts';\n\n/**\n * Schema → MongoDB `$jsonSchema` validator conversion. This is the ORM's\n * headline feature: one schema definition drives TS types AND server-side\n * document validation + collection creation.\n *\n * Mapping (mirrors sdk-db `convertJsonSchemaToMongoSchema`):\n * string→string, integer→int, number→number, double→double, long→long,\n * decimal→decimal, boolean→bool, date→date, objectId→objectId,\n * array→array(items), object→object(properties/required),\n * enum→enum (+bsonType), null→null, any→no constraint, raw→fragment verbatim.\n * The top-level `_id` is forced to `objectId` regardless of declared type.\n */\n\n/** Copy numeric keywords (min/max/exclusive/multipleOf) onto a fragment. */\nconst addNumericBounds = (\n out: MongoJsonSchema,\n field: {\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n },\n): MongoJsonSchema => {\n if (field.minimum !== undefined) out.minimum = field.minimum;\n if (field.maximum !== undefined) out.maximum = field.maximum;\n if (field.multipleOf !== undefined) out.multipleOf = field.multipleOf;\n if (field.exclusiveMinimum) out.exclusiveMinimum = true;\n if (field.exclusiveMaximum) out.exclusiveMaximum = true;\n return out;\n};\n\n/**\n * The Node driver picks the BSON wire type for a plain JS `number` by VALUE:\n * integral values in int32 range serialize as `int`, everything else as\n * `double` (and explicit `Long` instances as `long`). A single-type\n * `bsonType` therefore rejects perfectly type-correct TS values — e.g.\n * `bsonType: 'int'` rejects 3_000_000_000 (encoded as double), and\n * `bsonType: 'double'` rejects `{ rating: 5 }` (encoded as int). Numeric\n * kinds must accept every wire encoding their TS type can produce:\n * - `double` → ['double','int','long'] (any IEEE value the driver emits)\n * - `integer` → ['int','long','double'] + multipleOf: 1\n * - `long` → ['long','int','double'] + multipleOf: 1\n * For the integral kinds `multipleOf: 1` preserves SERVER-side integrality\n * enforcement that a bare double member of the union would otherwise lose.\n */\nconst NUMERIC_WIRE_UNION: Record<'double' | 'long', string[]> = {\n double: ['double', 'int', 'long'],\n long: ['long', 'int', 'double'],\n};\nconst INTEGER_WIRE_UNION = ['int', 'long', 'double'];\n\nconst convertField = (field: SchemaType): MongoJsonSchema => {\n // Raw escape hatch: pass the fragment through verbatim. A `description` on\n // the DSL field is merged only when the fragment doesn't already carry one.\n if (field.kind === 'raw') {\n const out = { ...field.fragment };\n if (field.description && !out.description) out.description = field.description;\n return out;\n }\n\n const out: MongoJsonSchema = {};\n if (field.description) out.description = field.description;\n\n switch (field.kind) {\n case 'string':\n out.bsonType = 'string';\n if (field.minLength !== undefined) out.minLength = field.minLength;\n if (field.maxLength !== undefined) out.maxLength = field.maxLength;\n if (field.pattern) out.pattern = field.pattern;\n // `format` is intentionally NOT emitted: MongoDB's `$jsonSchema` rejects the\n // keyword with `$jsonSchema keyword 'format' is not currently supported`, so\n // emitting it would make `createCollection`/`collMod` fail server-side. The\n // DSL option remains accepted for authoring intent, but it is a no-op here.\n return out;\n case 'number':\n out.bsonType = field.integer ? [...INTEGER_WIRE_UNION] : 'number';\n // Server-side integrality: the double member of the union would accept\n // fractional values — `multipleOf: 1` rejects them again.\n if (field.integer && field.multipleOf === undefined) out.multipleOf = 1;\n return addNumericBounds(out, field);\n case 'double':\n out.bsonType = [...NUMERIC_WIRE_UNION.double];\n return addNumericBounds(out, field);\n case 'long':\n out.bsonType = [...NUMERIC_WIRE_UNION.long];\n if (field.multipleOf === undefined) out.multipleOf = 1;\n return addNumericBounds(out, field);\n case 'decimal':\n out.bsonType = 'decimal';\n return addNumericBounds(out, field);\n case 'boolean':\n out.bsonType = 'bool';\n return out;\n case 'date':\n out.bsonType = 'date';\n return out;\n case 'objectId':\n out.bsonType = 'objectId';\n return out;\n case 'geoPoint':\n return {\n ...(field.description ? { description: field.description } : {}),\n bsonType: 'object',\n required: ['type', 'coordinates'],\n properties: {\n type: { enum: ['Point'] },\n coordinates: {\n bsonType: 'array',\n items: { bsonType: 'number' },\n minItems: 2,\n maxItems: 2,\n },\n },\n };\n case 'null':\n out.bsonType = 'null';\n return out;\n case 'any':\n return out;\n case 'enum': {\n out.enum = [...field.values];\n // `bsonType` and `enum` are AND-ed by Mongo's `$jsonSchema`. The old\n // behavior picked ONE bsonType from the first non-null member, which\n // silently excluded members of other types server-side (a mixed enum\n // like `s.enum(['a', 1])` only ever accepted strings). Emit the union\n // of every member's type so the enum set is the sole constraint:\n // ['a', 1] → bsonType ['string', 'int']\n // ['x', null] → bsonType ['string', 'null']\n // [1, 2, 3] → bsonType 'int' (unchanged)\n // [1, 2.5] → bsonType 'number' (matches every numeric BSON type)\n // [null] → bsonType 'null'\n const types = new Set<string>();\n for (const v of field.values) {\n if (v === null) types.add('null');\n else if (typeof v === 'string') types.add('string');\n else if (typeof v === 'number') {\n const allInt = field.values.every((x) => typeof x !== 'number' || Number.isInteger(x));\n // Out-of-int32-range members serialize as double — 'int' alone would\n // reject them, so fall back to the full numeric union.\n const fitsInt32 =\n allInt &&\n field.values.every(\n (x) => typeof x !== 'number' || (x >= -2147483648 && x <= 2147483647),\n );\n types.add(allInt && fitsInt32 ? 'int' : 'number');\n break; // 'int'/'number' already covers every numeric member\n }\n }\n if (types.size === 1) {\n out.bsonType = [...types][0]!;\n } else if (types.size > 1) {\n out.bsonType = [...types];\n }\n return out;\n }\n case 'array':\n out.bsonType = 'array';\n out.items = convertField(field.items);\n if (field.minItems !== undefined) out.minItems = field.minItems;\n if (field.maxItems !== undefined) out.maxItems = field.maxItems;\n if (field.uniqueItems) out.uniqueItems = true;\n return out;\n case 'object':\n return convertObject(field);\n }\n};\n\nconst convertObject = (field: ObjectField): MongoJsonSchema => {\n const out: MongoJsonSchema = { bsonType: 'object' };\n const required: string[] = [];\n const properties: Record<string, MongoJsonSchema> = {};\n\n for (const [key, prop] of Object.entries(field.properties)) {\n properties[key] = convertField(prop);\n if (!prop.flags.optional && !prop.flags.hasDefault) required.push(key);\n }\n\n if (required.length > 0) out.required = required;\n out.properties = properties;\n // Strict by default: the DB `$jsonSchema` validator is the ONLY runtime\n // validation layer (per project decision — no client-side schema validation),\n // so unknown fields are rejected unless a field explicitly opts out\n // (`additionalProperties: true`).\n out.additionalProperties = field.additionalProperties ?? false;\n if (field.minProperties !== undefined) out.minProperties = field.minProperties;\n if (field.maxProperties !== undefined) out.maxProperties = field.maxProperties;\n return out;\n};\n\n/**\n * ORM-managed lifecycle fields the library itself writes, reserved in the\n * validator so strict validation (`additionalProperties: false`) doesn't\n * reject them — the same treatment `_id` already gets:\n * `__v` — optimistic-lock version counter (`updateWithVersion`)\n * `deletedAt` — soft-delete marker (`softDeleteOne`); `null` means active\n * Only injected when the schema does NOT already declare the field. Exported\n * so the runtime drift validator (`validate-doc.ts`) stays in sync.\n */\nexport const ORM_RESERVED_FIELDS: Record<string, MongoJsonSchema> = {\n __v: { bsonType: 'int' },\n deletedAt: { bsonType: ['date', 'null'] },\n};\n\n/** Convert an object schema into a Mongo JSON-schema fragment (no `$jsonSchema` wrapper). */\nexport const toMongoSchema = (schema: ObjectField): MongoJsonSchema => {\n const result = convertObject(schema);\n result.properties ??= {};\n // Only inject `_id` when the schema does NOT declare it. MongoDB's default is\n // ObjectId, and because validation is strict by default the implicit `_id`\n // must be a declared property or every insert is rejected by the DB validator.\n // A user-declared `_id` is respected as-is (e.g. `s.string()` for string ids),\n // so the inferred TS type (InferDoc) and the DB validator stay in agreement.\n if (!result.properties._id) {\n result.properties._id = { bsonType: 'objectId' };\n }\n // Reserve the ORM's own lifecycle fields so soft-delete and optimistic\n // locking keep working under strict validation.\n for (const [key, fragment] of Object.entries(ORM_RESERVED_FIELDS)) {\n if (!result.properties[key]) result.properties[key] = fragment;\n }\n return result;\n};\n\n/** Full validator object ready for `createCollection({ validator })` / `collMod`. */\nexport const toMongoValidator = (schema: ObjectField): { $jsonSchema: MongoJsonSchema } => ({\n $jsonSchema: toMongoSchema(schema),\n});\n","/**\n * Typed schema DSL for `ninox`.\n *\n * Schemas are plain, serializable objects (kind + constraints + flags). They\n * serve three purposes at once:\n * 1. Derive the TypeScript document type (`InferDoc<T>`)\n * 2. Drive the fluent query builder's field typing\n * 3. Convert to a MongoDB `$jsonSchema` validator (`toMongoValidator`)\n *\n * Example:\n * const userSchema = s.object({\n * _id: s.objectId(),\n * email: s.string().optional(),\n * age: s.integer({ minimum: 0 }),\n * role: s.enum(['admin', 'user'] as const),\n * createdAt: s.date(),\n * });\n * type User = InferDoc<typeof userSchema>;\n */\nimport type { MongoJsonSchema } from './json-schema.ts';\n\nexport const SUPPORTED_STRING_FORMATS = new Set([\n 'email',\n 'uri',\n 'date-time',\n 'date',\n 'uuid',\n 'hostname',\n 'ipv4',\n 'ipv6',\n]);\n\nexport interface FieldFlags {\n optional: boolean;\n hasDefault: boolean;\n defaultValue?: unknown;\n}\n\nexport interface FieldMeta {\n kind: string;\n flags: FieldFlags;\n description?: string;\n}\n\nexport interface StringField extends FieldMeta {\n kind: 'string';\n format?: string;\n minLength?: number;\n maxLength?: number;\n pattern?: string;\n}\n\nexport interface IntegerField extends FieldMeta {\n kind: 'number';\n integer: true;\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n /** Draft-4 boolean form: `minimum` is excluded from the allowed range. */\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\nexport interface NumberField extends FieldMeta {\n kind: 'number';\n integer?: false;\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\n/** Strict BSON `double` (IEEE 754 float64) field. */\nexport interface DoubleField extends FieldMeta {\n kind: 'double';\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\n/** BSON `long` (int64) field — inferred as the driver's lossless `Long` type. */\nexport interface LongField extends FieldMeta {\n kind: 'long';\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\n/** Strict BSON `decimal` (Decimal128) field — inferred as `Decimal128`. */\nexport interface DecimalField extends FieldMeta {\n kind: 'decimal';\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\nexport interface BooleanField extends FieldMeta {\n kind: 'boolean';\n}\n\nexport interface DateField extends FieldMeta {\n kind: 'date';\n}\n\nexport interface ObjectIdField extends FieldMeta {\n kind: 'objectId';\n}\n\nexport interface ArrayField<I extends SchemaType = SchemaType> extends FieldMeta {\n kind: 'array';\n items: I;\n minItems?: number;\n maxItems?: number;\n uniqueItems?: boolean;\n}\n\nexport interface ObjectField<\n P extends Record<string, SchemaType> = Record<string, SchemaType>,\n N extends string = string,\n> extends FieldMeta {\n kind: 'object';\n properties: P;\n additionalProperties?: boolean;\n minProperties?: number;\n maxProperties?: number;\n /**\n * Optional collection name carried by the schema. When present, the schema is\n * the single source of truth for the collection name — `defineCollections`\n * keys the derived `collections` map by it.\n */\n name?: N;\n}\n\nexport interface EnumField<V extends readonly (string | number)[] = readonly (string | number)[]>\n extends FieldMeta {\n kind: 'enum';\n values: V;\n}\n\nexport interface AnyField extends FieldMeta {\n kind: 'any';\n}\n\nexport interface NullField extends FieldMeta {\n kind: 'null';\n}\n\nexport interface GeoPointField extends FieldMeta {\n kind: 'geoPoint';\n}\n\nexport interface RawField extends FieldMeta {\n kind: 'raw';\n /** Arbitrary `$jsonSchema` fragment passed through verbatim (escape hatch). */\n fragment: MongoJsonSchema;\n}\n\nexport type SchemaType =\n | StringField\n | IntegerField\n | NumberField\n | DoubleField\n | LongField\n | DecimalField\n | BooleanField\n | DateField\n | ObjectIdField\n | ArrayField\n | ObjectField\n | EnumField\n | AnyField\n | NullField\n | GeoPointField\n | RawField;\n\n/** A schema with chainable `.optional()` / `.default()` modifiers attached. */\nexport type Chainable<T extends SchemaType> = T & {\n optional(): Chainable<T & { flags: { optional: true } }>;\n default(value: unknown): Chainable<T & { flags: { hasDefault: true; defaultValue: unknown } }>;\n};\n\nconst chain = <T extends SchemaType>(field: T): Chainable<T> => {\n const obj = field as unknown as Chainable<T>;\n obj.optional = () => chain({ ...field, flags: { ...field.flags, optional: true } });\n obj.default = (value: unknown) =>\n chain({ ...field, flags: { ...field.flags, hasDefault: true, defaultValue: value } });\n return obj;\n};\n\nconst BASE = { flags: { optional: false, hasDefault: false } } as const;\n\n/**\n * Object schema factory (exposed as `s.object`). When `name` is provided the\n * returned schema carries it as a required literal, so `defineCollections` can\n * key the derived map by it and forget a name becomes a type error.\n */\nfunction objectField<P extends Record<string, SchemaType>, N extends string>(\n properties: P,\n opts: {\n additionalProperties?: boolean;\n minProperties?: number;\n maxProperties?: number;\n name: N;\n },\n): Chainable<ObjectField<P, N> & { name: N }>;\nfunction objectField<P extends Record<string, SchemaType>>(\n properties: P,\n opts?: { additionalProperties?: boolean; minProperties?: number; maxProperties?: number },\n): Chainable<ObjectField<P, string>>;\nfunction objectField<P extends Record<string, SchemaType>, N extends string = string>(\n properties: P,\n opts: {\n additionalProperties?: boolean;\n minProperties?: number;\n maxProperties?: number;\n name?: N;\n } = {},\n): Chainable<ObjectField<P, N> & { name?: N }> {\n return chain({ kind: 'object', properties, ...BASE, ...opts });\n}\n\n/** Numeric constraints shared by every numeric field kind. */\nexport type NumberBounds = {\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n};\n\nexport const s = {\n /** UTF-8 string field (optional `format` / length / regex constraints). */\n string(\n opts: { format?: string; minLength?: number; maxLength?: number; pattern?: string } = {},\n ): Chainable<StringField> {\n if (opts.format !== undefined && !SUPPORTED_STRING_FORMATS.has(opts.format)) {\n throw new Error(\n `Unsupported string format \"${opts.format}\"; supported: ${[...SUPPORTED_STRING_FORMATS].join(', ')}`,\n );\n }\n return chain({ kind: 'string', ...BASE, ...opts });\n },\n /** 32-bit integer field with optional bounds (min/max, exclusive, multipleOf). */\n integer(opts: NumberBounds = {}): Chainable<IntegerField> {\n return chain({ kind: 'number', integer: true, ...BASE, ...opts });\n },\n /** Double/float field with optional bounds (min/max, exclusive, multipleOf). */\n number(opts: NumberBounds = {}): Chainable<NumberField> {\n return chain({ kind: 'number', integer: false, ...BASE, ...opts });\n },\n /** Strict BSON `double` (IEEE 754 float64) field. */\n double(opts: NumberBounds = {}): Chainable<DoubleField> {\n return chain({ kind: 'double', ...BASE, ...opts });\n },\n /** Strict BSON `long` (int64) field — inferred as `number`. */\n long(opts: NumberBounds = {}): Chainable<LongField> {\n return chain({ kind: 'long', ...BASE, ...opts });\n },\n /** Strict BSON `decimal` (Decimal128) field — inferred as `Decimal128`. */\n decimal(opts: NumberBounds = {}): Chainable<DecimalField> {\n return chain({ kind: 'decimal', ...BASE, ...opts });\n },\n /** Boolean field. */\n boolean(): Chainable<BooleanField> {\n return chain({ kind: 'boolean', ...BASE });\n },\n /** UTC datetime field (BSON date). */\n date(): Chainable<DateField> {\n return chain({ kind: 'date', ...BASE });\n },\n /** MongoDB ObjectId field (`_id` and foreign keys). */\n objectId(): Chainable<ObjectIdField> {\n return chain({ kind: 'objectId', ...BASE });\n },\n /** Array of `items` (nested schema types allowed), with optional length/uniqueness. */\n array<I extends SchemaType>(\n items: I,\n opts: { minItems?: number; maxItems?: number; uniqueItems?: boolean } = {},\n ): Chainable<ArrayField<I>> {\n const field: ArrayField<I> = { kind: 'array', items, ...BASE, ...opts };\n return chain(field);\n },\n object: objectField,\n /** Enum union of literal string/number values. */\n enum<V extends readonly (string | number)[]>(values: V): Chainable<EnumField<V>> {\n const field: EnumField<V> = { kind: 'enum', values, ...BASE };\n return chain(field);\n },\n /** Unconstrained field (no validator bounds). */\n any(): Chainable<AnyField> {\n return chain({ kind: 'any', ...BASE });\n },\n /** Explicitly-nullable field. */\n null(): Chainable<NullField> {\n return chain({ kind: 'null', ...BASE });\n },\n /** GeoJSON Point field (type `Point` + `[lng, lat]` coordinates) for `2dsphere` queries. */\n geoPoint(): Chainable<GeoPointField> {\n return chain({ kind: 'geoPoint', ...BASE });\n },\n /**\n * Raw `$jsonSchema` escape hatch: pass an arbitrary fragment through verbatim\n * to the validator. Use for Mongo keywords the DSL doesn't model (e.g.\n * `patternProperties`, `allOf`, `anyOf`, `dependencies`).\n */\n jsonSchema(fragment: MongoJsonSchema): Chainable<RawField> {\n return chain({ kind: 'raw', fragment, ...BASE });\n },\n};\n\n/** Standalone modifier: mark a field as optional (`s.string().optional()` equivalent). */\nexport const optional = <T extends SchemaType>(\n field: T,\n): Chainable<T & { flags: { optional: true } }> =>\n chain({ ...field, flags: { ...field.flags, optional: true } });\n\n/** Standalone modifier: attach a default value. */\nexport const withDefault = <T extends SchemaType>(\n field: T,\n value: unknown,\n): Chainable<T & { flags: { hasDefault: true; defaultValue: unknown } }> =>\n chain({ ...field, flags: { ...field.flags, hasDefault: true, defaultValue: value } });\n","/**\n * Shared building blocks for the drift validator: issue recording, value\n * description / BSON-type checks, and numeric-bounds + reserved-field checks.\n * All pure — no schema/doc knowledge, just value-level helpers.\n */\nimport { Decimal128, Long, ObjectId } from 'mongodb';\nimport { ORM_RESERVED_FIELDS } from '../to-mongo-schema.ts';\nimport type { DriftIssue, DriftIssueCode } from './types.ts';\n\n/** Append a drift issue. */\nexport const push = (\n issues: DriftIssue[],\n path: string,\n code: DriftIssueCode,\n expected: string,\n message: string,\n): void => {\n issues.push({ path, code, expected, message });\n};\n\n/** Human-readable description of a runtime value (used in type-mismatch messages). */\nexport const describeValue = (value: unknown): string => {\n if (value instanceof ObjectId) return 'ObjectId';\n if (value instanceof Date) return 'Date';\n if (value === null) return 'null';\n if (Array.isArray(value)) return 'array';\n return typeof value;\n};\n\n/** Is `value` a plain BSON/JSON object — excludes arrays, dates, ObjectIds, RegExps. */\nexport const isPlainObject = (value: unknown): boolean =>\n typeof value === 'object' &&\n value !== null &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !(value instanceof ObjectId) &&\n !(value instanceof RegExp);\n\n/** Coerce a value to a finite number for numeric-constraint checks (BSON-aware). */\nexport const numericValue = (value: unknown): number | undefined => {\n if (value instanceof Decimal128) {\n const n = Number(value.toString());\n return Number.isNaN(n) ? undefined : n;\n }\n // `Long` above 2^53 loses precision via toNumber, but bounds checks are\n // advisory — skipping them silently (the old behavior) is worse.\n if (value instanceof Long) {\n const n = value.toNumber();\n return Number.isNaN(n) ? undefined : n;\n }\n if (typeof value === 'number' && !Number.isNaN(value)) return value;\n return undefined;\n};\n\n/** Shared numeric-bounds shape present on every numeric field kind. */\nexport interface NumericBounds {\n minimum?: number;\n maximum?: number;\n multipleOf?: number;\n exclusiveMinimum?: boolean;\n exclusiveMaximum?: boolean;\n}\n\n/** Emit drift issues for numeric bounds shared by every numeric field kind. */\nexport const checkNumericBounds = (\n field: NumericBounds,\n value: unknown,\n path: string,\n issues: DriftIssue[],\n): void => {\n const num = numericValue(value);\n if (num === undefined) return;\n if (\n field.minimum !== undefined &&\n (field.exclusiveMinimum ? num <= field.minimum : num < field.minimum)\n ) {\n push(\n issues,\n path,\n 'constraint',\n `minimum ${field.minimum}${field.exclusiveMinimum ? ' (exclusive)' : ''}`,\n `${num} out of range`,\n );\n }\n if (\n field.maximum !== undefined &&\n (field.exclusiveMaximum ? num >= field.maximum : num > field.maximum)\n ) {\n push(\n issues,\n path,\n 'constraint',\n `maximum ${field.maximum}${field.exclusiveMaximum ? ' (exclusive)' : ''}`,\n `${num} out of range`,\n );\n }\n if (field.multipleOf !== undefined && field.multipleOf > 0 && num % field.multipleOf !== 0) {\n push(\n issues,\n path,\n 'constraint',\n `multipleOf ${field.multipleOf}`,\n `${num} is not a multiple of ${field.multipleOf}`,\n );\n }\n};\n\n/** Does `value` satisfy a single `$jsonSchema` bsonType keyword? */\nexport const bsonTypeMatches = (bsonType: string | undefined, value: unknown): boolean => {\n switch (bsonType) {\n case 'objectId':\n return value instanceof ObjectId;\n case 'int':\n return typeof value === 'number' && Number.isInteger(value);\n case 'number':\n return typeof value === 'number' && !Number.isNaN(value);\n case 'string':\n return typeof value === 'string';\n case 'bool':\n return typeof value === 'boolean';\n case 'date':\n return value instanceof Date;\n case 'null':\n return value === null;\n case 'array':\n return Array.isArray(value);\n case 'object':\n return isPlainObject(value);\n case 'double':\n return typeof value === 'number' && !Number.isNaN(value);\n case 'long':\n return (typeof value === 'number' && Number.isInteger(value)) || value instanceof Long;\n case 'decimal':\n return value instanceof Decimal128;\n default:\n return true;\n }\n};\n\n/** Validate a value against a `MongoJsonSchema` fragment (used for reserved fields). */\nexport const checkReservedValue = (\n key: string,\n value: unknown,\n path: string,\n issues: DriftIssue[],\n): void => {\n const fragment = (ORM_RESERVED_FIELDS as Record<string, { bsonType?: string | string[] }>)[key];\n if (!fragment) return;\n const types = Array.isArray(fragment.bsonType) ? fragment.bsonType : [fragment.bsonType];\n if (types.some((t) => bsonTypeMatches(t, value))) return;\n push(\n issues,\n path,\n 'type',\n types.join(' | '),\n `Reserved field \"${key}\" must be ${types.join(' | ')}`,\n );\n};\n","import { BSON, type Document } from 'mongodb';\nimport type { MongoJsonSchema } from '../json-schema.ts';\nimport { push } from './helpers.ts';\nimport type { DriftIssue } from './types.ts';\n\ntype RawSchema = MongoJsonSchema & {\n allOf?: RawSchema[];\n anyOf?: RawSchema[];\n oneOf?: RawSchema[];\n not?: RawSchema;\n patternProperties?: Record<string, RawSchema>;\n dependencies?: Record<string, string[] | RawSchema>;\n};\n\nconst typeMatches = (value: unknown, type: string): boolean => {\n if (type === 'number') return typeof value === 'number' || value instanceof BSON.Long;\n if (type === 'int') {\n return value instanceof BSON.Int32 || (typeof value === 'number' && Number.isInteger(value));\n }\n if (type === 'long') {\n return value instanceof BSON.Long || (typeof value === 'number' && Number.isInteger(value));\n }\n if (type === 'double') return typeof value === 'number' || value instanceof BSON.Double;\n if (type === 'decimal') return value instanceof BSON.Decimal128;\n if (type === 'object')\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n if (type === 'array') return Array.isArray(value);\n if (type === 'string') return typeof value === 'string';\n if (type === 'bool' || type === 'boolean') return typeof value === 'boolean';\n if (type === 'date') return value instanceof Date;\n if (type === 'objectId') return value instanceof BSON.ObjectId;\n if (type === 'null') return value === null;\n if (type === 'binData') return value instanceof BSON.Binary;\n if (type === 'regex') return value instanceof RegExp;\n return true;\n};\n\nconst comparable = (value: unknown): number | undefined => {\n if (typeof value === 'number') return value;\n if (value instanceof BSON.Long || value instanceof BSON.Int32 || value instanceof BSON.Double) {\n return Number(value.toString());\n }\n if (value instanceof BSON.Decimal128) return Number(value.toString());\n return undefined;\n};\n\n/** Validate the MongoDB JSON-schema keywords accepted by the raw escape hatch. */\nexport const validateRawSchema = (\n schema: RawSchema,\n value: unknown,\n path: string,\n issues: DriftIssue[],\n): void => {\n const types = schema.bsonType === undefined ? [] : [schema.bsonType].flat();\n if (types.length > 0 && !types.some((type) => typeMatches(value, type))) {\n push(issues, path, 'type', types.join(' | '), 'BSON type does not match raw schema');\n return;\n }\n if (\n schema.enum &&\n !schema.enum.some(\n (candidate) => BSON.EJSON.stringify(candidate) === BSON.EJSON.stringify(value),\n )\n ) {\n push(issues, path, 'enum', 'raw enum', 'Value is not in the allowed set');\n }\n\n if (typeof value === 'string') {\n if (schema.minLength !== undefined && value.length < schema.minLength) {\n push(issues, path, 'constraint', `minLength ${schema.minLength}`, 'String is too short');\n }\n if (schema.maxLength !== undefined && value.length > schema.maxLength) {\n push(issues, path, 'constraint', `maxLength ${schema.maxLength}`, 'String is too long');\n }\n if (schema.pattern && !new RegExp(schema.pattern).test(value)) {\n push(\n issues,\n path,\n 'constraint',\n `pattern ${schema.pattern}`,\n 'String does not match pattern',\n );\n }\n }\n\n const numeric = comparable(value);\n if (numeric !== undefined) {\n const minimum =\n typeof schema.exclusiveMinimum === 'number' ? schema.exclusiveMinimum : schema.minimum;\n const maximum =\n typeof schema.exclusiveMaximum === 'number' ? schema.exclusiveMaximum : schema.maximum;\n if (\n minimum !== undefined &&\n (numeric < minimum || (schema.exclusiveMinimum === true && numeric === minimum))\n ) {\n push(issues, path, 'constraint', `minimum ${minimum}`, 'Number is below minimum');\n }\n if (\n maximum !== undefined &&\n (numeric > maximum || (schema.exclusiveMaximum === true && numeric === maximum))\n ) {\n push(issues, path, 'constraint', `maximum ${maximum}`, 'Number is above maximum');\n }\n if (\n schema.multipleOf !== undefined &&\n Math.abs(numeric / schema.multipleOf - Math.round(numeric / schema.multipleOf)) > 1e-9\n ) {\n push(\n issues,\n path,\n 'constraint',\n `multipleOf ${schema.multipleOf}`,\n 'Number is not a multiple',\n );\n }\n }\n\n if (Array.isArray(value)) {\n if (schema.minItems !== undefined && value.length < schema.minItems) {\n push(issues, path, 'constraint', `minItems ${schema.minItems}`, 'Array is too short');\n }\n if (schema.maxItems !== undefined && value.length > schema.maxItems) {\n push(issues, path, 'constraint', `maxItems ${schema.maxItems}`, 'Array is too long');\n }\n if (schema.uniqueItems) {\n const unique = new Set(value.map((item) => BSON.EJSON.stringify(item, { relaxed: false })));\n if (unique.size !== value.length) {\n push(issues, path, 'constraint', 'uniqueItems', 'Array contains duplicate items');\n }\n }\n if (Array.isArray(schema.items)) {\n schema.items.forEach((item, index) => {\n if (index < value.length)\n validateRawSchema(item, value[index], `${path}[${index}]`, issues);\n });\n } else if (schema.items) {\n value.forEach((item, index) => {\n validateRawSchema(schema.items as RawSchema, item, `${path}[${index}]`, issues);\n });\n }\n }\n\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n const object = value as Document;\n for (const required of schema.required ?? []) {\n if (object[required] === undefined)\n push(issues, `${path}.${required}`, 'missing', 'required', 'Required field is missing');\n }\n for (const [key, child] of Object.entries(schema.properties ?? {})) {\n if (key in object)\n validateRawSchema(child, object[key], path ? `${path}.${key}` : key, issues);\n }\n for (const [pattern, child] of Object.entries(schema.patternProperties ?? {})) {\n for (const key of Object.keys(object)) {\n if (new RegExp(pattern).test(key))\n validateRawSchema(child, object[key], `${path}.${key}`, issues);\n }\n }\n if (schema.additionalProperties === false) {\n const known = new Set([\n ...Object.keys(schema.properties ?? {}),\n ...Object.keys(object).filter((key) =>\n Object.keys(schema.patternProperties ?? {}).some((pattern) =>\n new RegExp(pattern).test(key),\n ),\n ),\n ]);\n for (const key of Object.keys(object)) {\n if (!known.has(key))\n push(\n issues,\n `${path}.${key}`,\n 'unknown_key',\n 'no additional properties',\n 'Unexpected field',\n );\n }\n } else if (typeof schema.additionalProperties === 'object') {\n for (const key of Object.keys(object)) {\n if (!(key in (schema.properties ?? {})))\n validateRawSchema(schema.additionalProperties, object[key], `${path}.${key}`, issues);\n }\n }\n const count = Object.keys(object).length;\n if (schema.minProperties !== undefined && count < schema.minProperties)\n push(\n issues,\n path,\n 'constraint',\n `minProperties ${schema.minProperties}`,\n 'Too few properties',\n );\n if (schema.maxProperties !== undefined && count > schema.maxProperties)\n push(\n issues,\n path,\n 'constraint',\n `maxProperties ${schema.maxProperties}`,\n 'Too many properties',\n );\n for (const [key, dependency] of Object.entries(schema.dependencies ?? {})) {\n if (!(key in object)) continue;\n if (Array.isArray(dependency)) {\n for (const required of dependency)\n if (!(required in object))\n push(issues, path, 'constraint', 'dependencies', `${key} requires ${required}`);\n } else validateRawSchema(dependency, object, path, issues);\n }\n }\n\n for (const child of schema.allOf ?? []) validateRawSchema(child, value, path, issues);\n if (schema.anyOf) {\n const matches = schema.anyOf.some((child) => {\n const candidate: DriftIssue[] = [];\n validateRawSchema(child, value, path, candidate);\n return candidate.length === 0;\n });\n if (!matches) push(issues, path, 'constraint', 'anyOf', 'No anyOf schema matched');\n }\n if (schema.oneOf) {\n const matches = schema.oneOf.filter((child) => {\n const candidate: DriftIssue[] = [];\n validateRawSchema(child, value, path, candidate);\n return candidate.length === 0;\n }).length;\n if (matches !== 1)\n push(issues, path, 'constraint', 'oneOf', 'Exactly one oneOf schema must match');\n }\n if (schema.not) {\n const candidate: DriftIssue[] = [];\n validateRawSchema(schema.not, value, path, candidate);\n if (candidate.length === 0)\n push(issues, path, 'constraint', 'not', 'Value matched a forbidden schema');\n }\n};\n","/**\n * Per-kind drift validators as a lookup table of pure functions — the\n * functional-composition replacement for what was a single giant `switch` over\n * `field.kind` in `validate-doc.ts`.\n *\n * Each validator receives `deps` (the shared recursive entry points\n * `validateValue` / `validateObjectProps`) so array/object kinds can recurse\n * without importing the orchestrator — breaking the import cycle and keeping\n * every field-kind rule small, isolated, and independently readable.\n */\nimport { isIP } from 'node:net';\nimport { Decimal128, type Document, Long, ObjectId } from 'mongodb';\nimport type {\n ArrayField,\n DecimalField,\n DoubleField,\n EnumField,\n LongField,\n NumberField,\n ObjectField,\n RawField,\n SchemaType,\n StringField,\n} from '../types.ts';\nimport { checkNumericBounds, describeValue, isPlainObject, push } from './helpers.ts';\nimport { validateRawSchema } from './raw.ts';\nimport type { DriftIssue } from './types.ts';\n\n/** The recursive entry points the per-kind validators use to descend. */\nexport interface FieldValidatorDeps {\n validateValue: (field: SchemaType, value: unknown, path: string, issues: DriftIssue[]) => void;\n validateObjectProps: (\n field: ObjectField,\n value: Document,\n path: string,\n issues: DriftIssue[],\n topLevel: boolean,\n ) => void;\n}\n\nexport type FieldValidator = (\n deps: FieldValidatorDeps,\n field: SchemaType,\n value: unknown,\n path: string,\n issues: DriftIssue[],\n) => void;\n\n/**\n * Compiled-pattern cache: `s.string({ pattern })` is compiled once per schema\n * field object instead of once per validated VALUE (the old\n * `new RegExp(f.pattern)` ran on every string of every document — measurable\n * GC pressure under `findMany` drift checks). Keyed weakly so schemas are not\n * kept alive by the cache.\n */\nconst patternCache = new WeakMap<object, RegExp>();\n\nconst compiledPattern = (field: StringField): RegExp | undefined => {\n if (!field.pattern) return undefined;\n const cached = patternCache.get(field);\n if (cached) return cached;\n try {\n const re = new RegExp(field.pattern);\n patternCache.set(field, re);\n return re;\n } catch {\n // Malformed pattern — nothing to enforce at runtime.\n return undefined;\n }\n};\n\nconst STRING_FORMAT_VALIDATORS: Record<string, (value: string) => boolean> = {\n email: (value) => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value),\n uri: (value) => {\n try {\n return new URL(value).protocol.length > 0;\n } catch {\n return false;\n }\n },\n 'date-time': (value) => /^\\d{4}-\\d{2}-\\d{2}T/.test(value) && !Number.isNaN(Date.parse(value)),\n date: (value) =>\n /^\\d{4}-\\d{2}-\\d{2}$/.test(value) && !Number.isNaN(Date.parse(`${value}T00:00:00Z`)),\n uuid: (value) =>\n /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(value),\n hostname: (value) => /^(?=.{1,253}$)[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?$/i.test(value),\n ipv4: (value) => isIP(value) === 4,\n ipv6: (value) => isIP(value) === 6,\n};\n\nconst stringValidator: FieldValidator = (_deps, field, value, path, issues) => {\n const f = field as StringField;\n if (typeof value !== 'string') {\n push(issues, path, 'type', 'string', `Expected string, got ${describeValue(value)}`);\n return;\n }\n if (f.minLength !== undefined && value.length < f.minLength) {\n push(\n issues,\n path,\n 'constraint',\n `string(minLength ${f.minLength})`,\n `Length ${value.length} < ${f.minLength}`,\n );\n }\n if (f.maxLength !== undefined && value.length > f.maxLength) {\n push(\n issues,\n path,\n 'constraint',\n `string(maxLength ${f.maxLength})`,\n `Length ${value.length} > ${f.maxLength}`,\n );\n }\n const pattern = compiledPattern(f);\n if (pattern && !pattern.test(value)) {\n push(\n issues,\n path,\n 'constraint',\n `string(pattern ${f.pattern})`,\n `\"${value}\" does not match pattern`,\n );\n }\n const format = f.format ? STRING_FORMAT_VALIDATORS[f.format] : undefined;\n if (format && !format(value)) {\n push(\n issues,\n path,\n 'constraint',\n `string(format ${f.format})`,\n `\"${value}\" is not a valid ${f.format}`,\n );\n }\n};\n\nconst numberValidator: FieldValidator = (_deps, field, value, path, issues) => {\n const f = field as NumberField;\n const expected = f.integer ? 'integer' : 'number';\n if (typeof value !== 'number' || Number.isNaN(value)) {\n push(issues, path, 'type', expected, `Expected ${expected}, got ${describeValue(value)}`);\n return;\n }\n if (f.integer && !Number.isInteger(value)) {\n push(issues, path, 'type', 'integer', `Expected integer, got ${value}`);\n }\n checkNumericBounds(f, value, path, issues);\n};\n\nconst floatingValidator: FieldValidator = (_deps, field, value, path, issues) => {\n const f = field as DoubleField | LongField | DecimalField;\n // `long` accepts both safe-range JS numbers and driver `Long` instances —\n // int64 values above 2^53 deserialized by another client come back as Long,\n // and flagging legitimately-stored large values as drift is a false positive.\n const ok =\n f.kind === 'decimal'\n ? value instanceof Decimal128\n : f.kind === 'long'\n ? (typeof value === 'number' && Number.isInteger(value)) || value instanceof Long\n : typeof value === 'number' && !Number.isNaN(value);\n if (!ok) {\n push(issues, path, 'type', f.kind, `Expected ${f.kind}, got ${describeValue(value)}`);\n return;\n }\n checkNumericBounds(f, value, path, issues);\n};\n\nconst booleanValidator: FieldValidator = (_deps, _field, value, path, issues) => {\n if (typeof value !== 'boolean') {\n push(issues, path, 'type', 'boolean', `Expected boolean, got ${describeValue(value)}`);\n }\n};\n\nconst dateValidator: FieldValidator = (_deps, _field, value, path, issues) => {\n if (!(value instanceof Date)) {\n push(issues, path, 'type', 'date', `Expected Date, got ${describeValue(value)}`);\n }\n};\n\nconst objectIdValidator: FieldValidator = (_deps, _field, value, path, issues) => {\n if (!(value instanceof ObjectId)) {\n push(issues, path, 'type', 'ObjectId', `Expected ObjectId, got ${describeValue(value)}`);\n }\n};\n\nconst geoPointValidator: FieldValidator = (_deps, _field, value, path, issues) => {\n if (!isPlainObject(value)) {\n push(issues, path, 'type', 'GeoPoint', `Expected GeoPoint object, got ${describeValue(value)}`);\n return;\n }\n const gp = value as Document;\n if (gp.type !== 'Point') {\n push(\n issues,\n path,\n 'enum',\n 'GeoPoint(type \"Point\")',\n `Expected type \"Point\", got ${JSON.stringify(gp.type)}`,\n );\n }\n const coords = gp.coordinates;\n if (\n !Array.isArray(coords) ||\n coords.length !== 2 ||\n !coords.every((c) => typeof c === 'number' && Number.isFinite(c))\n ) {\n push(\n issues,\n path,\n 'constraint',\n 'GeoPoint(coordinates: [lng, lat])',\n 'Expected [lng, lat] pair of finite numbers',\n );\n }\n};\n\nconst nullValidator: FieldValidator = (_deps, _field, value, path, issues) => {\n if (value !== null) {\n push(issues, path, 'type', 'null', `Expected null, got ${describeValue(value)}`);\n }\n};\n\nconst anyValidator: FieldValidator = () => {\n // `any` accepts any value — nothing to check.\n};\n\nconst rawValidator: FieldValidator = (_deps, field, value, path, issues) => {\n validateRawSchema((field as RawField).fragment, value, path, issues);\n};\n\nconst enumValidator: FieldValidator = (_deps, field, value, path, issues) => {\n const f = field as EnumField;\n if (!f.values.includes(value as never)) {\n push(\n issues,\n path,\n 'enum',\n `enum[${f.values.join(', ')}]`,\n `Value ${JSON.stringify(value)} is not in the allowed set`,\n );\n }\n};\n\nconst arrayValidator: FieldValidator = (deps, field, value, path, issues) => {\n const f = field as ArrayField;\n if (!Array.isArray(value)) {\n push(\n issues,\n path,\n 'type',\n `array<${f.items.kind}>`,\n `Expected array, got ${describeValue(value)}`,\n );\n return;\n }\n if (f.minItems !== undefined && value.length < f.minItems) {\n push(\n issues,\n path,\n 'constraint',\n `array(minItems ${f.minItems})`,\n `Length ${value.length} < ${f.minItems}`,\n );\n }\n if (f.maxItems !== undefined && value.length > f.maxItems) {\n push(\n issues,\n path,\n 'constraint',\n `array(maxItems ${f.maxItems})`,\n `Length ${value.length} > ${f.maxItems}`,\n );\n }\n if (f.uniqueItems) {\n const seen = new Set(\n value.map((item) =>\n item instanceof ObjectId\n ? item.toHexString()\n : typeof item === 'object' && item !== null\n ? JSON.stringify(item)\n : item,\n ),\n );\n if (seen.size !== value.length) {\n push(issues, path, 'constraint', 'array(uniqueItems)', 'Array contains duplicate items');\n }\n }\n value.forEach((item, i) => {\n deps.validateValue(f.items, item, `${path}[${i}]`, issues);\n });\n};\n\nconst objectValidator: FieldValidator = (deps, field, value, path, issues) => {\n const f = field as ObjectField;\n if (!isPlainObject(value)) {\n push(issues, path, 'type', 'object', `Expected object, got ${describeValue(value)}`);\n return;\n }\n deps.validateObjectProps(f, value as Document, path, issues, false);\n};\n\n/** Lookup table: field kind → validator. The single source of per-kind rules. */\nexport const FIELD_VALIDATORS: Record<SchemaType['kind'], FieldValidator> = {\n string: stringValidator,\n number: numberValidator,\n double: floatingValidator,\n long: floatingValidator,\n decimal: floatingValidator,\n boolean: booleanValidator,\n date: dateValidator,\n objectId: objectIdValidator,\n geoPoint: geoPointValidator,\n null: nullValidator,\n any: anyValidator,\n raw: rawValidator,\n enum: enumValidator,\n array: arrayValidator,\n object: objectValidator,\n};\n","/**\n * Drift-validation orchestrator: `validateValue` (dispatch to the per-kind\n * registry), `validateObjectProps` (declared properties + strict unknown-key\n * handling), and the public `validateDoc` entry point.\n *\n * Recursion between `validateValue` and `validateObjectProps` flows through the\n * `deps` object so neither this module nor `./field-validators.ts` imports the\n * other (no cycle).\n */\nimport type { Document } from 'mongodb';\nimport { ObjectId } from 'mongodb';\nimport { ORM_RESERVED_FIELDS } from '../to-mongo-schema.ts';\nimport type { ObjectField, SchemaType } from '../types.ts';\nimport { FIELD_VALIDATORS, type FieldValidatorDeps } from './field-validators.ts';\nimport { checkReservedValue, describeValue, push } from './helpers.ts';\nimport type { DriftIssue } from './types.ts';\n\n/** Validate a single value against its field schema, dispatching per kind. */\nfunction validateValue(\n field: SchemaType,\n value: unknown,\n path: string,\n issues: DriftIssue[],\n): void {\n const validator = FIELD_VALIDATORS[field.kind];\n if (validator) validator(deps, field, value, path, issues);\n}\n\n/** Validate an object's declared properties + strict unknown-key handling. */\nfunction validateObjectProps(\n field: ObjectField,\n value: Document,\n path: string,\n issues: DriftIssue[],\n topLevel: boolean,\n): void {\n const propPath = (key: string): string => (path ? `${path}.${key}` : key);\n\n for (const [key, prop] of Object.entries(field.properties)) {\n const present = key in value && value[key] !== undefined;\n if (!present) {\n if (!prop.flags.optional && !prop.flags.hasDefault) {\n push(issues, propPath(key), 'missing', prop.kind, `Required field \"${key}\" is missing`);\n }\n continue;\n }\n validateValue(prop, value[key], propPath(key), issues);\n }\n\n // Strict by default: mirror the validator's `additionalProperties: false`\n // unless the field opted out. The top level additionally allows the ORM's\n // reserved lifecycle fields (they are reserved in the $jsonSchema too).\n if (field.additionalProperties !== true) {\n const allowedReserved = topLevel ? ALLOWED_RESERVED_TOP : NO_RESERVED;\n for (const key of Object.keys(value)) {\n if (key in field.properties) continue;\n if (allowedReserved.has(key)) continue;\n push(\n issues,\n propPath(key),\n 'unknown_key',\n 'no additional properties',\n `Unexpected field \"${key}\"`,\n );\n }\n }\n\n const propCount = Object.keys(value).length;\n if (field.minProperties !== undefined && propCount < field.minProperties) {\n push(\n issues,\n path,\n 'constraint',\n `object(minProperties ${field.minProperties})`,\n `Has ${propCount} properties < ${field.minProperties}`,\n );\n }\n if (field.maxProperties !== undefined && propCount > field.maxProperties) {\n push(\n issues,\n path,\n 'constraint',\n `object(maxProperties ${field.maxProperties})`,\n `Has ${propCount} properties > ${field.maxProperties}`,\n );\n }\n\n // Type-check present-but-undeclared reserved lifecycle fields so drift in\n // `_id` / `__v` / `deletedAt` is surfaced too (mirrors toMongoSchema).\n if (topLevel) {\n if ('_id' in value && !('_id' in field.properties) && value._id !== undefined) {\n if (!(value._id instanceof ObjectId)) {\n push(issues, '_id', 'type', 'ObjectId', 'Reserved field \"_id\" must be ObjectId');\n }\n }\n for (const key of Object.keys(ORM_RESERVED_FIELDS)) {\n if (key in field.properties) continue;\n if (key in value && value[key] !== undefined) {\n checkReservedValue(key, value[key], key, issues);\n }\n }\n }\n}\n\n/** Recursive entry points shared by every validator (built after the functions above). */\nconst deps: FieldValidatorDeps = { validateValue, validateObjectProps };\n\n/**\n * Reserved top-level keys allowed under strict `additionalProperties`, hoisted\n * to module scope: allocating this Set per validated document was measurable\n * GC churn on the hot read path (drift defaults to 'report' — every uncached\n * read validates every document).\n */\nconst ALLOWED_RESERVED_TOP: ReadonlySet<string> = new Set([\n '_id',\n ...Object.keys(ORM_RESERVED_FIELDS),\n]);\nconst NO_RESERVED: ReadonlySet<string> = new Set<string>();\n\n/** Check a stored document against the declared schema; returns any drift issues. */\nexport const validateDoc = (schema: ObjectField, doc: Document): DriftIssue[] => {\n const issues: DriftIssue[] = [];\n if (doc === null || typeof doc !== 'object' || Array.isArray(doc)) {\n push(issues, '', 'type', 'object', `Expected a document object, got ${describeValue(doc)}`);\n return issues;\n }\n validateObjectProps(schema, doc, '', issues, true);\n return issues;\n};\n","/**\n * Logical → physical collection-name resolution.\n *\n * A collection is declared by a logical name; the physical name in MongoDB may\n * differ via a `collectionPrefix` (namespacing) or explicit per-collection\n * `collectionPhysicalNames` overrides. This module owns that mapping so the\n * rest of the ORM can always ask \"what physical name does this logical name\n * map to?\" via `createResolveCollectionName`.\n */\nexport const DEFAULT_COLLECTION_PREFIX_SEPARATOR = '-';\n/** Hard ceiling on MongoDB collection name length (server-enforced too). */\nexport const MAX_MONGODB_COLLECTION_NAME_BYTES = 255;\n\nexport interface ResolveCollectionConfig {\n /** Prepended to every physical name: `prefix + separator + logical`. */\n collectionPrefix?: string;\n /** Joins `collectionPrefix` and the logical name (default `-`). */\n collectionPrefixSeparator?: string;\n /** Per-logical-name physical overrides; wins over the prefix rule. */\n collectionPhysicalNames?: Partial<Record<string, string>>;\n}\n\n/**\n * Resolve a logical collection name → physical collection name.\n * - explicit `collectionPhysicalNames[logical]` wins\n * - otherwise `prefix + separator + logical`\n * - no prefix → identity\n */\nexport const createResolveCollectionName = (config: ResolveCollectionConfig) => {\n const sep = config.collectionPrefixSeparator ?? DEFAULT_COLLECTION_PREFIX_SEPARATOR;\n return (logical: string): string => {\n const override = config.collectionPhysicalNames?.[logical];\n if (override) return override;\n const prefix = config.collectionPrefix;\n if (!prefix) return logical;\n return `${prefix}${sep}${logical}`;\n };\n};\n","/**\n * Normalize a Mongo connection string so performance/reliability defaults are\n * explicit (mirrors sdk-db `normalizeMongoUrl`):\n * - retryWrites=false unless already set (keeps semantics predictable)\n * - w=1 unless another write concern is present\n * - directConnection=true ONLY for single-host, non-replica-set,\n * non-SRV URIs (`mongodb+srv` implies replica-set discovery — appending\n * `directConnection` there makes the driver reject the URI)\n *\n * Parsing is manual (string split + URLSearchParams) instead of WHATWG `new\n * URL`: the URL parser rejects multi-host seed lists (`h1:27017,h2:27017` —\n * it reads `,h2` as a port) and re-encodes userinfo/path in surprising ways.\n */\nexport const normalizeMongoUrl = (rawUrl: string): string => {\n try {\n const qIndex = rawUrl.indexOf('?');\n const base = qIndex === -1 ? rawUrl : rawUrl.slice(0, qIndex);\n const query = qIndex === -1 ? '' : rawUrl.slice(qIndex + 1);\n const params = new URLSearchParams(query);\n\n if (!params.has('retryWrites')) params.set('retryWrites', 'false');\n const hasWriteConcern =\n params.has('w') || params.has('wtimeoutMS') || params.has('writeConcern');\n if (!hasWriteConcern) params.set('w', '1');\n\n // Hosts live between '://' and the first '/' (userinfo may precede them,\n // separated by the LAST '@'). Commas separate seed-list members.\n const schemeSep = base.indexOf('://');\n const authority = schemeSep === -1 ? base : (base.slice(schemeSep + 3).split('/')[0] ?? '');\n const hostPart = authority.includes('@') ? (authority.split('@').pop() ?? '') : authority;\n const hostCount = hostPart === '' ? 0 : hostPart.split(',').length;\n const isSrv = base.startsWith('mongodb+srv://');\n if (!isSrv && hostCount === 1 && !params.has('replicaSet') && !params.has('directConnection')) {\n params.set('directConnection', 'true');\n }\n\n const queryString = params.toString();\n return queryString ? `${base}?${queryString}` : base;\n } catch {\n return rawUrl;\n }\n};\n","/**\n * Optional change-stream watchers that invalidate the shared query cache on\n * EXTERNAL writes — other processes, the raw `client` escape hatch, or direct\n * DB writes — closing the write-through-only gap of the ORM `QueryCache`.\n *\n * Requires a replica set / mongos. On standalone servers `$changeStream` is\n * rejected, so the invalidator logs a warning once and disables itself (the\n * cache then stays write-through only — see `MongoServiceConfig.cacheWatch`).\n *\n * One watcher is opened per unique (database, physical collection); any change\n * invalidates every cached read for that collection via\n * `QueryCache.invalidateByCollection`. Watchers self-heal: transient errors\n * retry with backoff and the collection is re-invalidated on reopen, so\n * changes missed during an outage don't leave stale entries behind.\n */\nimport type { ChangeStream, Db } from 'mongodb';\nimport type { QueryCache } from '../cache/query-cache.ts';\nimport { cacheCollectionKey } from '../cache/query-cache.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\nimport { sleepJittered } from '../utils/timeout.ts';\nimport { explainPermanentWatchError } from '../utils/watch-errors.ts';\n\n/** A collection whose external writes should invalidate cached reads. */\nexport interface CacheInvalidationRef {\n /** Raw `Db` handle (e.g. `service.db.primaryClient.client`). */\n db: Db;\n /** PHYSICAL collection name — cache keys use it, so invalidation must too. */\n collection: string;\n /** Stable deployment identity shared with the manager's cache keys. */\n namespace?: string;\n}\n\nconst SEP = '\\u0000';\n\nexport class CacheInvalidator {\n private cache: QueryCache;\n private logger: LoggerLike;\n private streams = new Map<string, ChangeStream>();\n private disabled = false;\n private stopped = true;\n private warnedUnsupported = false;\n\n constructor(options: { cache: QueryCache; logger: LoggerLike }) {\n this.cache = options.cache;\n this.logger = options.logger;\n }\n\n /** Number of currently open change streams. */\n get size(): number {\n return this.streams.size;\n }\n\n /**\n * Open one watcher per unique (database, physical collection). Idempotent:\n * already-open streams are skipped; after `stop()` a later `start()` reopens.\n * Never throws — failures are logged (on unsupported servers it disables once).\n */\n async start(refs: CacheInvalidationRef[]): Promise<void> {\n if (this.disabled) return;\n this.stopped = false;\n const seen = new Set<string>();\n for (const ref of refs) {\n const key = `${ref.db.databaseName}${SEP}${ref.collection}`;\n if (seen.has(key) || this.streams.has(key)) continue;\n seen.add(key);\n // Never float as an unhandled rejection — an escape from the loop's\n // catch handler would crash the process.\n void this.watchLoop(key, ref).catch((err) => {\n this.logger.error?.(\n { error: err instanceof Error ? err.message : String(err), collection: ref.collection },\n 'cacheWatch: watcher crashed',\n );\n });\n }\n }\n\n /** Close every watcher. Safe to call repeatedly, and before any `start`. */\n async stop(): Promise<void> {\n this.stopped = true;\n const closes = [...this.streams.values()].map((stream) => {\n try {\n return Promise.resolve(stream.close()).catch(() => {});\n } catch {\n return Promise.resolve();\n }\n });\n this.streams.clear();\n await Promise.allSettled(closes);\n }\n\n private async watchLoop(key: string, ref: CacheInvalidationRef): Promise<void> {\n let backoff = 0;\n while (!this.stopped) {\n // A stream healthy for a long stretch before failing is an isolated\n // blip — reset escalation (backoff is for REPEATED failures).\n let connectedAt = Date.now();\n try {\n const stream = ref.db.collection(ref.collection).watch([]);\n // Prevent EventEmitter crashes between events; keep diagnostics.\n stream.on('error', (err) => {\n this.logger.debug?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'cacheWatch: stream error event',\n );\n });\n this.streams.set(key, stream);\n connectedAt = Date.now();\n if (backoff > 0) {\n // Reconnect after an outage: changes during the gap were missed, so\n // drop the collection's cache to force a re-fetch on the next read.\n this.cache.invalidateByCollection(\n cacheCollectionKey(ref.db.databaseName, ref.collection, ref.namespace),\n );\n }\n const iterator = stream[Symbol.asyncIterator]();\n for await (const _change of iterator) {\n this.cache.invalidateByCollection(\n cacheCollectionKey(ref.db.databaseName, ref.collection, ref.namespace),\n );\n }\n } catch (err) {\n if (Date.now() - connectedAt > 60_000) backoff = 0;\n const message = err instanceof Error ? err.message : String(err);\n const abandoned = this.streams.get(key);\n this.streams.delete(key);\n if (abandoned) {\n try {\n await abandoned.close();\n } catch {\n // Best-effort — the server drops the cursor on disconnect anyway.\n }\n }\n const verdict = explainPermanentWatchError(message);\n if (verdict) {\n // Every collection shares the same server, so one permanent verdict\n // applies to all — disable once and stop retrying. NOTE: match ONLY\n // definitive permanent errors; replica errors like \"change stream\n // history lost\" (collection dropped) or resume-token expiry must stay\n // in the retry path.\n this.disabled = true;\n if (!this.warnedUnsupported) {\n this.warnedUnsupported = true;\n // One short line + the fix: an operator reading the log should not\n // have to know what \"permanent\" means (or guess which knob to turn).\n this.logger.warn?.(\n {\n collection: ref.collection,\n reason: verdict.reason,\n error: message,\n hint: verdict.hint,\n },\n `cacheWatch: disabled — ${verdict.headline}; the query cache stays write-through only`,\n );\n }\n return;\n }\n if (this.stopped) return;\n this.logger.warn?.(\n { error: message, collection: ref.collection },\n 'cacheWatch: change stream error, retrying with backoff',\n );\n backoff = Math.min(backoff + 1000, 5000);\n await sleepJittered(backoff, 1000, true);\n }\n }\n }\n}\n","/**\n * Logger abstraction. The ORM never logs directly — it accepts any logger that\n * satisfies `LoggerLike` (pino, a console wrapper, a test stub, ...). This keeps\n * the package free of logging dependencies while remaining observability-agnostic.\n */\nexport interface LogFn {\n (obj: Record<string, unknown>, msg?: string): void;\n (msg: string): void;\n}\n\nexport interface LoggerLike {\n debug: LogFn;\n info: LogFn;\n warn: LogFn;\n error: LogFn;\n}\n\n/** A logger that swallows everything. Useful in tests / perf runs. */\nexport const createNoopLogger = (): LoggerLike => ({\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n});\n\nconst LEVELS = ['debug', 'info', 'warn', 'error'] as const;\nexport type LogLevel = (typeof LEVELS)[number];\n\nconst LEVEL_RANK: Record<LogLevel, number> = { debug: 10, info: 20, warn: 30, error: 40 };\n\nconst fmtObj = (obj: Record<string, unknown>): string => {\n try {\n return JSON.stringify(obj);\n } catch {\n return String(obj);\n }\n};\n\n/**\n * A tiny console logger matching the `LoggerLike` shape. `level` filters output.\n */\nexport const createConsoleLogger = (level: LogLevel = 'info'): LoggerLike => {\n const threshold = LEVEL_RANK[level];\n const make = (method: 'debug' | 'info' | 'warn' | 'error') => {\n const rank = LEVEL_RANK[method];\n const fn: LogFn = (a: unknown, b?: string) => {\n if (rank < threshold) return;\n const obj = typeof a === 'string' ? undefined : (a as Record<string, unknown>);\n const msg = typeof a === 'string' ? a : b;\n const prefix = obj !== undefined ? fmtObj(obj) : '';\n if (msg && prefix) {\n // eslint-disable-next-line no-console\n console[method](`[${method.toUpperCase()}]`, prefix, msg);\n } else {\n // eslint-disable-next-line no-console\n console[method](`[${method.toUpperCase()}]`, (msg ?? prefix) as string);\n }\n };\n return fn;\n };\n return {\n debug: make('debug'),\n info: make('info'),\n warn: make('warn'),\n error: make('error'),\n };\n};\n","/**\n * Service configuration: the `MongoServiceConfig` options type, cache policy\n * resolution (`resolveCache`), and runtime-config derivation\n * (`resolveRuntimeConfig`). Pure — no connection or manager wiring here, so the\n * config concerns of the service are isolated from the composition root.\n */\nimport { QueryCache, type QueryCacheOptions } from '../cache/query-cache.ts';\nimport type { DriftMode } from '../schema/validate-doc/index.ts';\nimport { createConsoleLogger, type LoggerLike } from '../utils/logger.ts';\nimport type { DebugQuery } from './trace-db-op.ts';\n\n/**\n * Performance is ON by default. Resolve the service-level cache:\n * `undefined` → a default `QueryCache()`; `QueryCacheOptions` → constructed;\n * `QueryCache` → reused; `null` → disabled.\n */\nexport const resolveCache = (\n value: QueryCache | QueryCacheOptions | null | undefined,\n): QueryCache | undefined => {\n if (value === null) return undefined;\n if (value === undefined) return new QueryCache();\n if (value instanceof QueryCache) return value;\n return new QueryCache(value);\n};\n\nexport interface MongoServiceConfig {\n defaultDb?: string;\n migrationDir?: string;\n appName?: string;\n logger?: LoggerLike;\n /** Explicit host tracer (Ignex debugQuery); null disables the optional probe. */\n debugQuery?: DebugQuery | null;\n /**\n * Map driver errors to typed DomainError/InfraError before rethrowing. ON by\n * default — set `false` to surface raw driver errors instead.\n */\n wrapMongoErrors?: boolean;\n /**\n * Read-through query cache shared by every CRUD read. ON by default:\n * `undefined` creates a default `QueryCache()`, `QueryCacheOptions` builds\n * one, a `QueryCache` is reused, and `null` disables caching.\n *\n * INVALIDATION: entries are dropped write-through — every ORM write\n * invalidates that collection's cached reads. External writers (other\n * processes, the raw `client` escape hatch, direct DB writes) do NOT\n * invalidate. The default 30-second TTL bounds staleness; `ttlMs: 0`\n * explicitly selects unbounded entries. Multi-writer deployments can disable\n * the cache, route latency-critical reads through the\n * change-stream aware `createHotCache()`, or set `cacheWatch: true`.\n */\n cache?: QueryCache | QueryCacheOptions | null;\n /**\n * Opt into change-stream invalidation of the shared query cache. When `true`\n * (and a cache is enabled), after `makeConnections()` one `$changeStream`\n * watcher is opened per registered collection; any write — including external\n * ones — invalidates that collection's cached reads. Requires a replica set /\n * mongos. On standalone servers the streams are rejected, a warning is logged\n * once, and invalidation silently disables (the cache stays write-through\n * only). Watchers self-heal across transient errors and are closed by\n * `closeConnections()`. Default: false.\n */\n cacheWatch?: boolean;\n /** Permit transaction callbacks to run non-atomically on unsupported servers. Default: false. */\n allowNonTransactionalFallback?: boolean;\n /** Coalesce identical concurrent reads into one driver call. ON by default. */\n dedupeReads?: boolean;\n /**\n * Master performance switch. `perf: false` disables the query cache and\n * in-flight dedup even when the granular options are set. Defaults to true.\n */\n perf?: boolean;\n /** Validate inserts and replacements against the schema before sending them. Default: true. */\n validateWrites?: boolean;\n /**\n * Schema-drift policy for reads. When a document fetched from the DB\n * (cache-miss) doesn't match its declared schema:\n * - `'report'` (default) — log a warning with the offending fields, return as-is\n * - `'throw'` — throw `DomainError SCHEMA_DRIFT` (the document is never\n * cached or returned)\n * - `'off'` — no drift checking (previous behavior)\n * Detection-only: documents are never mutated. Projected reads ignore absent\n * fields but validate returned values. Overridable via `QueryOptions.drift`.\n */\n drift?: DriftMode;\n}\n\n/** The resolved, environment-merged runtime config shared by the whole service. */\nexport interface ResolvedServiceConfig {\n config: { defaultDb: string; migrationDir: string; appName: string };\n logger: LoggerLike;\n perfEnabled: boolean;\n sharedCache: QueryCache | undefined;\n dedupeReads: boolean;\n wrapMongoErrors: boolean;\n}\n\n/**\n * Merge `MongoServiceConfig` overrides with environment defaults and derive the\n * performance flags (cache/dedup/wrapMongoErrors). Called once by\n * `createMongoService`.\n */\nexport const resolveRuntimeConfig = (\n configOverrides: MongoServiceConfig,\n): ResolvedServiceConfig => {\n const config = {\n defaultDb: configOverrides.defaultDb ?? process.env.MONGO_URL ?? 'mongodb://localhost:27017/',\n migrationDir: configOverrides.migrationDir ?? process.env.MIGRATION_DIR ?? './migrations',\n appName: configOverrides.appName ?? process.env.APP_NAME ?? 'unknown-app',\n };\n const logger = configOverrides.logger ?? createConsoleLogger();\n // Perf is ON by default; `perf: false` (or the granular opt-outs) disable it.\n const perfEnabled = configOverrides.perf !== false;\n const sharedCache = perfEnabled ? resolveCache(configOverrides.cache) : undefined;\n const dedupeReads = perfEnabled ? (configOverrides.dedupeReads ?? true) : false;\n // Driver errors are mapped to typed DomainError/InfraError by default so a\n // framework can forward them to the client; `wrapMongoErrors: false` opts out.\n const wrapMongoErrors = configOverrides.wrapMongoErrors !== false;\n return { config, logger, perfEnabled, sharedCache, dedupeReads, wrapMongoErrors };\n};\n","import { MongoClient } from 'mongodb';\nimport type { DbClientsDefinition } from '../types.ts';\nimport { normalizeMongoUrl } from './connection-uri.ts';\n\nexport interface CoreConfigLike {\n defaultDb: string;\n}\n\n/**\n * Resolve the connection string for a client key:\n * 1. `dbClients[key].dbUrl` (normalized)\n * 2. env `DB_<CONSTANT_CASE_KEY>`\n * 3. `config.defaultDb`\n */\nexport const makeGetDbUrl =\n (dbClients: DbClientsDefinition, config: CoreConfigLike) =>\n (name: string): string => {\n const clientConfig = dbClients[name];\n if (clientConfig?.dbUrl) return normalizeMongoUrl(clientConfig.dbUrl);\n const envName = `DB_${name.replace(/[^a-zA-Z0-9]/g, '_').toUpperCase()}`;\n const envUrl = process.env[envName];\n if (envUrl) return normalizeMongoUrl(envUrl);\n return normalizeMongoUrl(config.defaultDb);\n };\n\n/**\n * Open one MongoClient per unique URL (clients sharing a URL share a pool),\n * then build a manager for each logical client. On any failure every client\n * opened *in this call* is closed and rolled back so no partial state remains.\n *\n * Connects are SINGLE-FLIGHT per URL: concurrent `makeConnections()` calls\n * await the same connect promise instead of each constructing a client (the\n * check-then-act alternative leaked the loser's socket pool forever — it was\n * registered in neither the pool nor the rollback list).\n */\nexport const makeConnectionFactory = <TClients extends DbClientsDefinition>(\n dbClients: TClients,\n db: Record<string, unknown>,\n getDbUrl: (name: string) => string,\n buildManager: (dbKey: string, dbName: string, client: MongoClient) => unknown,\n openedClients: Map<string, MongoClient> = new Map(),\n) => {\n /** In-progress connects by URL (cleared once settled). */\n const connecting = new Map<string, Promise<MongoClient>>();\n let transition = Promise.resolve();\n\n const connect = async (names?: (keyof TClients & string)[]): Promise<void> => {\n const keys = (names && names.length > 0 ? names : Object.keys(dbClients)) as Array<\n keyof TClients & string\n >;\n const openedThisCall: Array<{ url: string; client: MongoClient }> = [];\n const assignedThisCall: string[] = [];\n\n try {\n for (const key of keys) {\n const definition = dbClients[key]!;\n const dbUrl = getDbUrl(key);\n let client = openedClients.get(dbUrl);\n if (!client) {\n const inflight = connecting.get(dbUrl);\n if (inflight) {\n // Another concurrent call is already connecting this URL — share it.\n client = await inflight;\n } else {\n const attempt = (async () => {\n const c = new MongoClient(dbUrl, {\n connectTimeoutMS: definition.connectTimeoutMs ?? 10_000,\n serverSelectionTimeoutMS: definition.connectTimeoutMs ?? 10_000,\n monitorCommands: definition.monitorCommands ?? false,\n ...(definition.readPreference && { readPreference: definition.readPreference }),\n ...(definition.readConcern && { readConcern: definition.readConcern }),\n ...(definition.writeConcern && { writeConcern: definition.writeConcern }),\n });\n // Swallow driver-level 'error' events (e.g. connection\n // interruption during close) so they never surface as unhandled\n // rejections. Topology failures still reject in-flight ops.\n c.on('error', () => {});\n await c.connect();\n return c;\n })();\n connecting.set(dbUrl, attempt);\n try {\n client = await attempt;\n openedClients.set(dbUrl, client);\n openedThisCall.push({ url: dbUrl, client });\n } finally {\n connecting.delete(dbUrl);\n }\n }\n }\n const dbKey = `${key}Client`;\n db[dbKey] = buildManager(key, definition.name, client);\n assignedThisCall.push(dbKey);\n }\n } catch (err) {\n await Promise.allSettled(openedThisCall.map(({ client }) => client.close()));\n for (const { url } of openedThisCall) openedClients.delete(url);\n // Remove managers assigned earlier in this call so `db` never holds a\n // handle whose MongoClient was just closed (dangling manager on partial\n // failure — the next makeConnections overwrites them anyway).\n for (const dbKey of assignedThisCall) delete db[dbKey];\n throw err;\n }\n };\n\n return (names?: (keyof TClients & string)[]): Promise<void> => {\n const result = transition.then(() => connect(names));\n transition = result.catch(() => {});\n return result;\n };\n};\n\n/** Close every pooled client and clear the pool. All closes are attempted and\n * any failures are surfaced together after the pool has been cleared. */\nexport const closeConnections = async (openedClients: Map<string, MongoClient>): Promise<void> => {\n const results = await Promise.allSettled(\n [...openedClients.values()].map((client) => client.close()),\n );\n openedClients.clear();\n const errors = results\n .filter((result): result is PromiseRejectedResult => result.status === 'rejected')\n .map((result) => result.reason as unknown);\n if (errors.length > 0) throw new AggregateError(errors, 'Failed to close MongoDB connections');\n};\n","/**\n * Health check: pings every connected manager's raw `Db` handle in parallel\n * (with a configurable timeout per ping, default 2s) and reports per-DB latency,\n * failure reasons + overall status. Types and implementation live together here\n * so `service/index.ts` stays a thin composition root.\n */\nimport type { Db } from 'mongodb';\nimport { withTimeout } from '../utils/timeout.ts';\n\nexport interface DbHealthResult {\n /** Logical db client key (e.g. `primary`). */\n name: string;\n ok: boolean;\n /** Ping round-trip time in ms (present when `ok`). */\n latencyMs?: number;\n /** Why the ping failed — timeout vs auth vs network (present when `!ok`). */\n error?: string;\n}\n\nexport interface HealthReport {\n /**\n * Overall status. `false` when ANY db fails — including the degenerate\n * \"no dbs connected\" case (an empty manager record is NOT healthy).\n */\n ok: boolean;\n /** Total elapsed time across all pings in ms. */\n latencyMs: number;\n dbs: DbHealthResult[];\n}\n\n/** Build a `health()` implementation over the service's manager record. */\nexport const createHealth =\n (db: Record<string, unknown>, options: { timeoutMs?: number } = {}) =>\n async (): Promise<HealthReport> => {\n const started = performance.now();\n const timeoutMs = options.timeoutMs ?? 2_000;\n const dbs = await Promise.all(\n Object.entries(db).map(async ([key, manager]): Promise<DbHealthResult> => {\n const name = key.replace(/Client$/, '');\n const handle = (manager as { client?: Db } | undefined)?.client;\n if (!handle) return { name, ok: false, error: 'no client handle on manager' };\n try {\n const t0 = performance.now();\n await withTimeout(handle.admin().command({ ping: 1 }), timeoutMs, `health:${name}`);\n return { name, ok: true, latencyMs: performance.now() - t0 };\n } catch (err) {\n // Keep the WHY (timeout/auth/DNS collapse into the same boolean\n // otherwise and operators can't triage). Message only — no stacks.\n return {\n name,\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n }),\n );\n return {\n ok: dbs.length > 0 && dbs.every((r) => r.ok),\n latencyMs: performance.now() - started,\n dbs,\n };\n };\n","import type { ClientSession, Document, Filter, ReadConcernLike, ReadPreferenceLike } from 'mongodb';\nimport { BadRequest } from '../errors/index.ts';\nimport { canonicalKey, DataLoader } from '../loader/dataloader.ts';\nimport type { RelationDef } from './relation.ts';\n\nexport interface PopulateDeps {\n /** Fetch docs from a (logical) collection by filter. */\n findMany: (\n collection: string,\n filter: Filter<Document>,\n options?: {\n projection?: Document;\n limit?: number;\n session?: ClientSession;\n maxTimeMS?: number;\n readPreference?: ReadPreferenceLike;\n readConcern?: ReadConcernLike;\n queryCache?: boolean;\n },\n ) => Promise<Document[]>;\n}\n\nexport interface PopulateOptions {\n maxBatchSize?: number;\n /** Cache keys only within this populate call (default true). */\n cache?: boolean;\n /** Opt into the shared read-through query cache (default false for fresh joins). */\n queryCache?: boolean;\n /** Safety cap per foreign-key batch. Exceeding it throws instead of truncating. */\n maxDocs?: number;\n session?: ClientSession;\n maxTimeMS?: number;\n readPreference?: ReadPreferenceLike;\n readConcern?: ReadConcernLike;\n}\n\n/**\n * Batch + cache loader for one foreign key path. `$in`-queries one foreign\n * collection per relation (regardless of how many source docs reference it),\n * which is what turns N+1 population into 1+N.\n */\nconst createForeignKeyLoader = (\n deps: PopulateDeps,\n collection: string,\n foreignField: string,\n options: PopulateOptions = {},\n): DataLoader<unknown, Document[]> =>\n new DataLoader<unknown, Document[]>({\n ...(options.maxBatchSize !== undefined ? { maxBatchSize: options.maxBatchSize } : {}),\n ...(options.cache !== undefined ? { cache: options.cache } : {}),\n keyOf: canonicalKey,\n batch: async (keys) => {\n const docs = await deps.findMany(\n collection,\n { [foreignField]: { $in: keys } },\n {\n limit: options.maxDocs !== undefined ? options.maxDocs + 1 : 0,\n ...(options.session !== undefined ? { session: options.session } : {}),\n ...(options.maxTimeMS !== undefined ? { maxTimeMS: options.maxTimeMS } : {}),\n ...(options.readPreference !== undefined\n ? { readPreference: options.readPreference }\n : {}),\n ...(options.readConcern !== undefined ? { readConcern: options.readConcern } : {}),\n ...(options.queryCache !== undefined ? { queryCache: options.queryCache } : {}),\n },\n );\n if (options.maxDocs !== undefined && docs.length > options.maxDocs) {\n throw new BadRequest(\n `populate: ${collection}.${foreignField} exceeded maxDocs ${options.maxDocs}; raise the cap or narrow the relation`,\n );\n }\n // Index foreign docs by canonical key value so distinct-but-equal keys\n // (e.g. two ObjectId instances with the same hex) resolve correctly.\n const index = new Map<string, Document[]>();\n for (const doc of docs) {\n const value = (doc as Document)[foreignField];\n const canonical = canonicalKey(value);\n const bucket = index.get(canonical) ?? [];\n bucket.push(doc);\n index.set(canonical, bucket);\n }\n const map = new Map<unknown, Document[]>();\n for (const key of keys) {\n map.set(key, index.get(canonicalKey(key)) ?? []);\n }\n return map;\n },\n });\n\nconst distinctKeys = (values: unknown[]): unknown[] => {\n const seen = new Set<string>();\n const out: unknown[] = [];\n for (const value of values) {\n if (value === undefined || value === null) continue;\n const canonical = canonicalKey(value);\n if (!seen.has(canonical)) {\n seen.add(canonical);\n out.push(value);\n }\n }\n return out;\n};\n\n/**\n * Resolve relations on an array of documents using DataLoader-batched queries.\n * Source documents are COPIED (shallow) before joining — populating a result\n * set that came from the shared query cache must never mutate the cached\n * entry (a cached order would otherwise carry join data into every later\n * reader of that cache entry). Returns the copies typed with joined fields.\n *\n * Independent relations resolve concurrently; relations sharing a target\n * collection + foreign field share ONE DataLoader batch.\n *\n * const orders = await users.findMany('orders', { userId });\n * const [withCustomer] = ... // orders[i].customer is now the joined Customer document\n * const populated = await populate(orders, [\n * belongsTo({ collection: 'customers', localField: 'customerId', as: 'customer' }),\n * ]);\n */\nexport const makePopulator = (deps: PopulateDeps) => {\n const populate = async <T extends Document>(\n docs: T[],\n relations: RelationDef[],\n options: PopulateOptions = {},\n ): Promise<Array<T & Record<string, unknown>>> => {\n // Copy-on-write: attach joins onto fresh copies so shared/cached\n // documents are never polluted (see module doc).\n const out = docs.map((doc) => ({ ...doc })) as Array<T & Record<string, unknown>>;\n if (out.length === 0 || relations.length === 0) return out;\n\n // One loader per (collection, foreignField) per call: two relations\n // targeting the same collection share a single `$in` batch instead of\n // issuing duplicate queries.\n const loaderCache = new Map<string, DataLoader<unknown, Document[]>>();\n const loaderFor = (\n collection: string,\n foreignField: string,\n ): DataLoader<unknown, Document[]> => {\n const cacheKey = `${collection}\\u0000${foreignField}`;\n let loader = loaderCache.get(cacheKey);\n if (!loader) {\n loader = createForeignKeyLoader(deps, collection, foreignField, options);\n loaderCache.set(cacheKey, loader);\n }\n return loader;\n };\n\n /** Load + index foreign docs for one hop: canonical key → matching docs. */\n const loadIndex = async (\n collection: string,\n foreignField: string,\n keys: unknown[],\n ): Promise<Map<string, Document[]>> => {\n const values = await loaderFor(collection, foreignField).loadMany(keys);\n const byKey = new Map<string, Document[]>();\n keys.forEach((key, i) => {\n byKey.set(canonicalKey(key), (values[i] as Document[] | undefined) ?? []);\n });\n return byKey;\n };\n\n await Promise.all(\n relations.map(async (relation) => {\n const target = relation.foreignField ?? '_id';\n const sourceKeys = distinctKeys(out.map((doc) => (doc as Document)[relation.localField]));\n\n if (relation.type === 'belongsTo') {\n const byKey = await loadIndex(relation.collection, target, sourceKeys);\n for (const doc of out) {\n const key = (doc as Document)[relation.localField];\n const matches =\n key === undefined || key === null ? undefined : byKey.get(canonicalKey(key));\n (doc as Record<string, unknown>)[relation.as] =\n matches?.[0] ?? (relation.optional ? undefined : null);\n }\n } else if (relation.type === 'hasMany') {\n const byKey = await loadIndex(relation.collection, target, sourceKeys);\n for (const doc of out) {\n const key = (doc as Document)[relation.localField];\n (doc as Record<string, unknown>)[relation.as] =\n key === undefined || key === null ? [] : (byKey.get(canonicalKey(key)) ?? []);\n }\n } else {\n // manyToMany: source → join docs → target docs (two batched hops).\n const throughByKey = await loadIndex(\n relation.through.collection,\n relation.through.localField,\n sourceKeys,\n );\n const joinDocs = [...throughByKey.values()].flat();\n const targetKeys = distinctKeys(\n joinDocs.map((join) => (join as Document)[relation.through.foreignField]),\n );\n const targetByKey = await loadIndex(relation.collection, target, targetKeys);\n\n for (const doc of out) {\n const key = (doc as Document)[relation.localField];\n const joins =\n key === undefined || key === null ? [] : (throughByKey.get(canonicalKey(key)) ?? []);\n // Dedupe targets: duplicate pivot rows pointing at the same\n // target must not repeat it in the populated array.\n const seenTargets = new Set<string>();\n const targets: Document[] = [];\n for (const join of joins) {\n const tk = canonicalKey((join as Document)[relation.through.foreignField]);\n if (seenTargets.has(tk)) continue;\n seenTargets.add(tk);\n const bucket = targetByKey.get(tk);\n if (bucket) targets.push(...bucket);\n }\n (doc as Record<string, unknown>)[relation.as] = targets;\n }\n }\n }),\n );\n return out;\n };\n\n return { populate };\n};\n\nexport type Populator = ReturnType<typeof makePopulator>;\n","import type {\n CreateIndexesOptions,\n IndexDirection,\n ReadConcernLike,\n ReadPreferenceLike,\n WriteConcern,\n} from 'mongodb';\nimport type { HookMap } from './hooks/hooks.ts';\nimport type { InferDoc } from './schema/infer.ts';\nimport type { ObjectField } from './schema/types.ts';\n\n/** A Mongo index definition usable by `createIndexes`. */\nexport interface IndexSpec {\n key: Record<string, IndexDirection>;\n options?: CreateIndexesOptions;\n}\n\n/** Auto-timestamp field names maintained by the ORM when `timestamps` is set. */\nexport interface CollectionTimestamps {\n /** Field stamped with the creation time on insert (default `createdAt`). */\n createdAt?: string;\n /** Field stamped with the modification time on every update (default `updatedAt`). */\n updatedAt?: string;\n}\n\n/**\n * Collection definition. A value of `collections` may be either a raw object\n * schema (`s.object({...})`) or a `CollectionDefinition` carrying optional\n * indexes + hooks.\n */\nexport interface CollectionDefinition<TSchema extends ObjectField = ObjectField> {\n schema: TSchema;\n indexes?: IndexSpec[];\n hooks?: HookMap<InferDoc<TSchema>>;\n /**\n * Auto-maintain timestamps on create/update. `true` uses the defaults\n * (`createdAt`/`updatedAt`); an object names custom fields. Fields must exist\n * in the schema for the values to be stamped.\n */\n timestamps?: CollectionTimestamps | boolean;\n}\n\nexport type CollectionLike = CollectionDefinition<any> | ObjectField;\n\n/**\n * One logical Mongo database. Keys of `collections` are the *logical* collection\n * names used in every ORM call; physical names are derived via\n * `collectionPrefix` / `collectionPhysicalNames`.\n */\nexport interface DBClientDefinition<\n TCollections extends Record<string, CollectionLike> = Record<string, CollectionLike>,\n> {\n /** Actual MongoDB database name. */\n name: string;\n /** Connection string. Falls back to env `DB_<CONSTANT_CASE_KEY>`, then config.defaultDb. */\n dbUrl?: string;\n collections: TCollections;\n /** Prefix applied to every logical collection name to produce the physical name. */\n collectionPrefix?: string;\n collectionPrefixSeparator?: string;\n /** Per-logical-collection physical-name overrides. */\n collectionPhysicalNames?: Partial<Record<string, string>>;\n connectTimeoutMs?: number;\n /** Enable driver command events before pools open (required for wire tracing). */\n monitorCommands?: boolean;\n readPreference?: ReadPreferenceLike;\n readConcern?: ReadConcernLike;\n writeConcern?: WriteConcern;\n}\n\nexport type DbClientsDefinition = Record<\n string,\n DBClientDefinition<Record<string, CollectionLike>>\n>;\n\n/* ------------------------------------------------------------------ *\n * Schema-first type inference. Call sites never pass `<TDoc>` —\n * the collection-name literal derives the document type automatically.\n * ------------------------------------------------------------------ */\n\nexport type NormalizeCollection<T> = T extends { kind: 'object' }\n ? { schema: T }\n : T extends CollectionDefinition\n ? T\n : never;\n\nexport type CollectionSchema<T> =\n T extends CollectionDefinition<infer S> ? S : T extends ObjectField ? T : never;\n\nexport type CollectionDoc<T> =\n T extends CollectionDefinition<infer S>\n ? InferDoc<S>\n : T extends ObjectField\n ? InferDoc<T>\n : never;\n\nexport type ExtractDbNames<TClients extends DbClientsDefinition> = keyof TClients & string;\n\nexport type ExtractCollectionNames<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> = keyof TClients[TDb]['collections'] & string;\n\nexport type ExtractCollectionType<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n TCollection extends ExtractCollectionNames<TClients, TDb>,\n> = CollectionDoc<TClients[TDb]['collections'][TCollection]>;\n\n/** Runtime normalization: schema-or-definition → `{ schema, indexes, hooks, timestamps }`. */\nexport const asCollectionDefinition = (\n value: CollectionLike,\n): {\n schema: ObjectField;\n indexes: IndexSpec[];\n hooks: HookMap;\n timestamps?: CollectionTimestamps;\n} => {\n if (value && typeof value === 'object' && 'schema' in value) {\n const def = value as CollectionDefinition;\n const ts = def.timestamps;\n const timestamps =\n ts === true\n ? { createdAt: 'createdAt', updatedAt: 'updatedAt' }\n : ts && typeof ts === 'object'\n ? ts\n : undefined;\n return {\n schema: def.schema,\n indexes: def.indexes ?? [],\n hooks: def.hooks ?? {},\n ...(timestamps ? { timestamps } : {}),\n };\n }\n return { schema: value as ObjectField, indexes: [], hooks: {} };\n};\n","import { mapMongoDriverError } from '../errors/index.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\n\n/** Structured metadata attached to every logged DB operation. */\nexport interface DbOpMeta {\n collection: string;\n physicalCollection?: string;\n db: string;\n op: string;\n /**\n * What was sent to the database (filter / document / update / pipeline /\n * options). Surfaced in the ignex debugbar as the span's `params`, so the\n * dashboard shows exactly what the query carried — not just its name.\n * Optional: ops without a payload worth showing omit it.\n */\n params?: unknown;\n}\n\nexport interface TraceDbOpOptions {\n /** Map driver errors to typed DomainError/InfraError before rethrowing. */\n wrapMongoErrors?: boolean;\n /**\n * Test/advanced seam: inject the ignex-debugbar `debugQuery` implementation\n * directly. Omitted (production) → probed lazily via `@ignex/core/debug`.\n * `null` forces the plain pass-through without touching the probe cache.\n */\n debugQuery?: DebugQuery | null;\n}\n\n/**\n * The ignex-debugbar `debugQuery` free helper (`@ignex/core/debug`), resolved\n * lazily so the ORM stays standalone: `undefined` until probed, `null` when\n * `@ignex/core` is not installed (plain ORM usage), the function otherwise.\n * `debugQuery` itself is a zero-cost pass-through when no request trace is\n * active, so production ignex apps pay nothing either.\n */\nexport type DebugQuery = <T>(\n sql: string,\n params: unknown,\n fn: () => T | Promise<T>,\n) => T | Promise<T>;\n\nlet debugQueryCache: DebugQuery | null | undefined;\n\n/** Probe once per process; the failed dynamic import is caught and cached. */\nconst probeDebugQuery = async (): Promise<void> => {\n if (debugQueryCache !== undefined) return;\n try {\n const mod = (await import('@ignex/core/debug')) as { debugQuery?: DebugQuery };\n debugQueryCache = typeof mod.debugQuery === 'function' ? mod.debugQuery : null;\n } catch {\n debugQueryCache = null;\n }\n};\n\n/**\n * Make a captured param payload JSON-safe before it reaches the debugbar: a\n * JSON round-trip strips `undefined` keys, RegExps, class instances and other\n * values that would otherwise crash `JSON.stringify` downstream (the live API\n * and the SQLite history both serialize span attrs). Mongo filters may carry\n * such values (`_id` ObjectIds serialize to their hex string; Dates to ISO\n * strings — exactly what a developer wants to see). Falls back to `String()`\n * when even the round-trip fails.\n */\nconst sanitizeDebugParams = (value: unknown): unknown => {\n try {\n return JSON.parse(JSON.stringify(value));\n } catch {\n try {\n return String(value);\n } catch {\n return '[unserializable]';\n }\n }\n};\n\n/**\n * Wrap a DB operation with start/ok/error structured logging (duration, op,\n * collection, db). When `wrapMongoErrors` is set, driver errors are mapped to\n * the ORM's typed error classes before being rethrown.\n *\n * When the app runs inside ignex with the debugbar enabled, every operation\n * is ALSO recorded as a `db` span in the current request's trace (`kind:\n * \"db\"`) — it shows up in the debugbar waterfall, the Queries tab and the\n * per-request db-time aggregate. The integration is optional and automatic:\n * it activates only when `@ignex/core` is installed AND a request trace is\n * active, and costs a single cached module probe otherwise.\n *\n * Caveat: the hook only fires when the dynamic `@ignex/core/debug` probe\n * resolves to the SAME module instance as the app's debugbar plugin (the\n * plugin's tracer gates on its own `tracingEnabled`). That is the case for a\n * normal npm install of both packages — but if this ORM is `bun link`-ed into\n * an app whose build cannot resolve `@ignex/core/debug` from the linked path,\n * the bundler externalizes the probe and it silently no-ops (no `db` spans).\n * Install `@ignex/core` alongside the app (npm-style) to keep the integration.\n */\nexport const traceDbOp = async <T>(\n logger: LoggerLike,\n meta: DbOpMeta,\n fn: () => T | Promise<T>,\n options: TraceDbOpOptions = {},\n): Promise<T> => {\n const start = performance.now();\n logger.debug({ ...meta, operation: 'start' }, 'start');\n try {\n // First op only: resolve the optional ignex-debugbar hook. An explicitly\n // injected `options.debugQuery` (tests / advanced hosts) wins over the\n // lazily-probed `@ignex/core/debug` helper.\n let debugQuery = options.debugQuery;\n if (debugQuery === undefined) {\n if (debugQueryCache === undefined) await probeDebugQuery();\n debugQuery = debugQueryCache;\n }\n // Pass WHAT WAS SENT (filter/doc/pipeline/…) as the span's params so the\n // debugbar shows the actual query payload, not just `collection.op`.\n const params = meta.params === undefined ? undefined : sanitizeDebugParams(meta.params);\n const result = debugQuery\n ? ((await debugQuery(`${meta.collection}.${meta.op}`, params, () => fn())) as T)\n : await fn();\n const durationMs = performance.now() - start;\n logger.info({ ...meta, durationMs }, 'ok');\n return result;\n } catch (err) {\n const durationMs = performance.now() - start;\n const loggable =\n err instanceof Error\n ? { name: err.name, message: err.message, code: (err as { code?: unknown }).code }\n : err;\n logger.error({ ...meta, durationMs, error: loggable }, 'error');\n if (options.wrapMongoErrors) throw mapMongoDriverError(err, meta);\n throw err;\n }\n};\n","/**\n * Shared op-pipeline deps for the `make*Ops` factories.\n *\n * Every op factory (`crud`, `pagination`, `aggregation`) used to hand-build the\n * same `{ trace, meta }` pair: structured start/ok/error logging + op metadata.\n * This module builds that pair once from `(logger, dbLabel, resolve,\n * wrapMongoErrors)` so the boilerplate lives in exactly one place.\n */\nimport type { LoggerLike } from '../utils/logger.ts';\nimport type { DbOpMeta, DebugQuery } from './trace-db-op.ts';\nimport { traceDbOp } from './trace-db-op.ts';\n\nexport interface OpDeps<TC> {\n /** Log a start/ok/error trace around one DB call (optional driver-error mapping). */\n trace: <T>(meta: DbOpMeta, fn: () => T | Promise<T>) => Promise<T>;\n /** Structured log metadata for a (collection, op) + optional sent-payload. */\n meta: (collection: TC, op: string, params?: unknown) => DbOpMeta;\n}\n\n/** Build the `{ trace, meta }` op-pipeline deps shared by every op factory. */\nexport const makeOpDeps = <TC>(\n logger: LoggerLike,\n dbLabel: string,\n resolve: (logical: string) => string,\n wrapMongoErrors: boolean,\n debugQuery?: DebugQuery | null,\n): OpDeps<TC> => {\n const trace = <T>(meta: DbOpMeta, fn: () => T | Promise<T>): Promise<T> =>\n traceDbOp(logger, meta, fn, {\n wrapMongoErrors,\n ...(debugQuery !== undefined ? { debugQuery } : {}),\n });\n const meta = (collection: TC, op: string, params?: unknown): DbOpMeta => ({\n collection: String(collection),\n physicalCollection: resolve(String(collection)),\n db: dbLabel,\n op,\n ...(params !== undefined ? { params } : {}),\n });\n return { trace, meta };\n};\n","import type {\n ClientSession,\n CollationOptions,\n Document,\n Hint,\n ReadConcernLike,\n ReadPreferenceLike,\n WriteConcern,\n} from 'mongodb';\nimport type { DriftMode } from '../schema/validate-doc/index.ts';\n\n/**\n * SDK-level query options. These are separated from driver options so the\n * public API surface stays stable against driver changes. `resolveQueryOptions`\n * strips them out and forwards the remainder untouched to the driver.\n */\nexport interface QueryOptions {\n session?: ClientSession;\n maxTimeMS?: number;\n hint?: Hint;\n /** Retry attempts for transient errors (default 3). */\n maxAttempts?: number;\n /** Base retry backoff in ms (default 150, exponential). */\n retryDelayMs?: number;\n batchSize?: number;\n /**\n * Per-op in-flight dedup override. `true` forces dedup on, `false` forces it\n * off (even when the service default is on); unset inherits the service\n * `dedupeReads` default.\n */\n dedupe?: boolean;\n /** Per-op read-cache bypass. `false` skips the cache for this read. */\n cache?: boolean;\n /**\n * Per-op write-retry override. Reads always retry transient errors; writes\n * retry ONLY when `retryWrites: true` (retrying a write is at-least-once —\n * a committed write whose ack was lost would be re-executed, so enable only\n * for idempotent writes). Default: off for write ops.\n */\n /**\n * Per-op write-retry override. Reads always retry transient errors; writes\n * retry ONLY when `retryWrites: true` (retrying a write is at-least-once —\n * a committed write whose ack was lost would be re-executed, so enable only\n * for idempotent writes). Default: off for write ops.\n */\n retryWrites?: boolean;\n /**\n * Per-op schema-drift policy override for reads (see `MongoServiceConfig.drift`).\n * `true` → `'throw'`, `false` → `'off'`, or an explicit `DriftMode` string.\n * Unset inherits the service-level default (`'report'`). Only checked when a\n * document is fetched from the DB (cache-miss); projections ignore absent\n * required fields but still validate returned values.\n */\n drift?: DriftMode | boolean;\n /** Driver-level options forwarded untouched to the underlying call. */\n collation?: CollationOptions;\n readPreference?: ReadPreferenceLike;\n readConcern?: ReadConcernLike;\n writeConcern?: WriteConcern;\n comment?: string | Document;\n let?: Document;\n timeoutMS?: number;\n}\n\nexport interface ResolvedQueryOptions<TDriverOpts = Record<string, unknown>> {\n maxAttempts: number;\n retryDelayMs: number;\n /** Tri-state: `undefined` inherits the service-level default. */\n dedupe?: boolean;\n /** Tri-state: `undefined` inherits the service-level default. */\n cache?: boolean;\n /** Write ops retry transient errors only when this is `true`. */\n retryWrites?: boolean;\n sdk: {\n session?: ClientSession;\n maxTimeMS?: number;\n hint?: Hint;\n batchSize?: number;\n drift?: DriftMode | boolean;\n };\n driverOpts: TDriverOpts;\n}\n\nexport const resolveQueryOptions = <T extends QueryOptions>(\n options?: T,\n): ResolvedQueryOptions<Omit<T, keyof QueryOptions>> => {\n // Clamp to >= 1 so `maxAttempts: 0` (a common \"disable retry\" attempt) can\n // never reach `withRetry` and produce a `throw undefined`.\n const maxAttempts = Math.max(1, options?.maxAttempts ?? 3);\n const retryDelayMs = options?.retryDelayMs ?? 150;\n const {\n session,\n maxTimeMS,\n hint,\n batchSize,\n drift,\n maxAttempts: _ma,\n retryDelayMs: _rd,\n dedupe,\n cache,\n retryWrites,\n ...rest\n } = options ?? {};\n return {\n maxAttempts,\n retryDelayMs,\n ...(dedupe !== undefined ? { dedupe } : {}),\n ...(cache !== undefined ? { cache } : {}),\n ...(retryWrites !== undefined ? { retryWrites } : {}),\n sdk: {\n ...(session !== undefined ? { session } : {}),\n ...(maxTimeMS !== undefined ? { maxTimeMS } : {}),\n ...(hint !== undefined ? { hint } : {}),\n ...(batchSize !== undefined ? { batchSize } : {}),\n ...(drift !== undefined ? { drift } : {}),\n },\n driverOpts: rest as Omit<T, keyof QueryOptions>,\n };\n};\n\n/** Build driver option objects omitting undefined SDK fields (exactOptionalPropertyTypes). */\nexport const pickSdkOptions = (sdk: {\n session?: unknown;\n maxTimeMS?: unknown;\n hint?: unknown;\n batchSize?: unknown;\n drift?: unknown;\n}): Record<string, unknown> => ({\n ...(sdk.session !== undefined ? { session: sdk.session } : {}),\n ...(sdk.maxTimeMS !== undefined ? { maxTimeMS: sdk.maxTimeMS } : {}),\n ...(sdk.hint !== undefined ? { hint: sdk.hint } : {}),\n ...(sdk.batchSize !== undefined ? { batchSize: sdk.batchSize } : {}),\n ...(sdk.drift !== undefined ? { drift: sdk.drift } : {}),\n});\n\n/**\n * Resolve the effective drift mode for a read: per-op override wins, then the\n * service default, else `'report'`.\n */\nexport const resolveDriftMode = (\n perOp: DriftMode | boolean | undefined,\n serviceDefault: DriftMode | undefined,\n): DriftMode => {\n if (perOp === true) return 'throw';\n if (perOp === false) return 'off';\n if (perOp === 'off' || perOp === 'report' || perOp === 'throw') return perOp;\n return serviceDefault ?? 'report';\n};\n","import { withRetry } from '../mongo-helpers.ts';\nimport {\n type QueryOptions,\n type ResolvedQueryOptions,\n resolveQueryOptions,\n} from './query-options.ts';\nimport type { DbOpMeta } from './trace-db-op.ts';\n\nexport interface CrudOpDeps<TCollection> {\n trace: <T>(meta: DbOpMeta, fn: () => T | Promise<T>) => Promise<T>;\n meta: (collection: TCollection, op: string, params?: unknown) => DbOpMeta;\n}\n\n/**\n * The uniform op wrapper every CRUD method funnels through:\n * resolve SDK options → trace (structured logs) → retry on transient errors.\n *\n * `execute` receives the resolved options so methods only declare the driver\n * options they forward.\n */\nexport const defineCrudOp = async <TCollection, TResult>(\n deps: CrudOpDeps<TCollection>,\n collection: TCollection,\n opName: string,\n execute: (resolved: ResolvedQueryOptions) => TResult | Promise<TResult>,\n options?: QueryOptions,\n write = false,\n /** What was sent to the DB (filter/doc/pipeline) — recorded in the debugbar. */\n params?: unknown,\n): Promise<TResult> => {\n const resolved = resolveQueryOptions(options);\n // Writes are at-least-once: retry them only when the caller opts in via\n // `retryWrites: true`. Reads are idempotent and always retried.\n const maxAttempts = write && resolved.retryWrites !== true ? 1 : resolved.maxAttempts;\n return deps.trace(deps.meta(collection, opName, params), async () =>\n withRetry(async () => execute(resolved), {\n maxAttempts,\n delayMs: resolved.retryDelayMs,\n }),\n );\n};\n","/**\n * Fully type-safe, chainable aggregation pipeline builder.\n *\n * Every stage is typed against the current document shape, so intellisense\n * follows the real schema fields and the result type of `.toArray()` /\n * `.first()` is inferred through the whole chain. `$lookup` sub-pipelines are\n * scoped to the related collection's schema and `$facet` branches get their own\n * typed sub-builder — see `src/service/pipeline-types.ts` for the type model.\n *\n * const top = await db.pipeline('orders')\n * .match({ status: 'paid' })\n * .group({ _id: '$userId', total: { $sum: '$total' } })\n * .sort({ total: -1 })\n * .limit(3)\n * .toArray();\n */\nimport type {\n AggregateOptions,\n AggregationCursor,\n ClientSession,\n Collection,\n Document,\n Hint,\n} from 'mongodb';\nimport { BadRequest } from '../errors/index.ts';\nimport type { FilterInput } from '../shared/filter-types.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../types.ts';\nimport type { CachedAggregate } from './aggregation/types.ts';\nimport { type CrudOpDeps, defineCrudOp } from './crud-op.ts';\nimport type {\n Added,\n FacetOutput,\n FacetSpec,\n ForeignDocOf,\n GeoNearOutput,\n GeoNearSpec,\n Grouped,\n GroupSpec,\n LookupJoinedFor,\n LookupSpecFor,\n Projected,\n Projection,\n SortKeys,\n Unsetted,\n UnwindSpec,\n Unwound,\n} from './pipeline-types.ts';\nimport type { QueryOptions, ResolvedQueryOptions } from './query-options.ts';\n\n/** Execution dependencies wired up by `makeAggregationOps`. */\nexport interface PipelineBuilderDeps {\n logical: string;\n coll: () => Collection<Document>;\n crudDeps: CrudOpDeps<string>;\n mergeDriver: (\n driverOpts: Record<string, unknown>,\n sdk: { session?: ClientSession; maxTimeMS?: number; hint?: Hint },\n ) => AggregateOptions;\n options?: AggregateOptions & QueryOptions;\n /**\n * Cached-aggregation runner (write-through cache + dedup). Present on real\n * builders so `.toArray()` / `.first()` are cached; absent on stage-only\n * builders (sub-pipelines read via `.raw()` and never execute).\n */\n cachedAggregate?: CachedAggregate;\n}\n\nexport class PipelineBuilder<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n TDoc extends Document,\n> {\n constructor(\n private readonly deps: PipelineBuilderDeps,\n private readonly stages: Document[] = [],\n ) {}\n\n /** Raw accumulated stages — embeddable into `$lookup` / `$facet` branches. */\n raw(): Document[] {\n return this.stages;\n }\n\n private assertNonNegativeFinite(name: string, n: number): void {\n if (!Number.isFinite(n) || n < 0) {\n throw new BadRequest(`pipeline.${name}(): ${name} must be a non-negative finite number`);\n }\n }\n\n /* --------------------------- shape-keeping --------------------------- */\n\n match(filter: FilterInput<TDoc>): this {\n this.stages.push({ $match: filter });\n return this;\n }\n\n sort(sort: SortKeys<TDoc>): this {\n this.stages.push({ $sort: sort });\n return this;\n }\n\n limit(n: number): this {\n this.assertNonNegativeFinite('limit', n);\n this.stages.push({ $limit: n });\n return this;\n }\n\n skip(n: number): this {\n this.assertNonNegativeFinite('skip', n);\n this.stages.push({ $skip: n });\n return this;\n }\n\n sample(n: number): this {\n this.assertNonNegativeFinite('sample', n);\n this.stages.push({ $sample: { size: n } });\n return this;\n }\n\n /**\n * `$geoNear` — requires a `2dsphere`/`2d` index and MUST be the first stage.\n * Adds the computed distance to `spec.distanceField` on every output doc.\n */\n geoNear<const S extends GeoNearSpec>(\n spec: S,\n ): PipelineBuilder<TClients, TDb, GeoNearOutput<TDoc, S>> {\n if (this.stages.length > 0) {\n throw new Error('pipeline.geoNear(): $geoNear must be the first pipeline stage');\n }\n return this.derive<GeoNearOutput<TDoc, S>>({ $geoNear: spec });\n }\n\n /* --------------------------- shape-changing -------------------------- */\n\n project<const P extends Projection<TDoc>>(\n projection: P,\n ): PipelineBuilder<TClients, TDb, Projected<TDoc, P>> {\n return this.derive<Projected<TDoc, P>>({ $project: projection });\n }\n\n addFields<const P extends Projection<TDoc>>(\n fields: P,\n ): PipelineBuilder<TClients, TDb, Added<TDoc, P>> {\n return this.derive<Added<TDoc, P>>({ $addFields: fields });\n }\n\n set<const P extends Projection<TDoc>>(fields: P): PipelineBuilder<TClients, TDb, Added<TDoc, P>> {\n return this.derive<Added<TDoc, P>>({ $set: fields });\n }\n\n unset<const F extends string | readonly string[]>(\n fields: F,\n ): PipelineBuilder<TClients, TDb, Unsetted<TDoc, F>> {\n return this.derive<Unsetted<TDoc, F>>({ $unset: fields });\n }\n\n count<const F extends string>(field: F): PipelineBuilder<TClients, TDb, { [K in F]: number }> {\n return this.derive<{ [K in F]: number }>({ $count: field });\n }\n\n group<const G extends GroupSpec<TDoc>>(\n group: G,\n ): PipelineBuilder<TClients, TDb, Grouped<TDoc, G>> {\n return this.derive<Grouped<TDoc, G>>({ $group: group });\n }\n\n unwind<const P extends UnwindSpec>(path: P): PipelineBuilder<TClients, TDb, Unwound<TDoc, P>> {\n return this.derive<Unwound<TDoc, P>>({ $unwind: path });\n }\n\n lookup<\n const F extends ExtractCollectionNames<TClients, TDb>,\n const A extends string,\n const O extends Document = ForeignDocOf<TClients, TDb, F>,\n >(\n spec: LookupSpecFor<TClients, TDb, TDoc, F> & {\n as: A;\n pipeline?:\n | Document[]\n | ((\n sub: PipelineBuilder<TClients, TDb, ForeignDocOf<TClients, TDb, F>>,\n ) => PipelineBuilder<TClients, TDb, O> | Document[]);\n },\n ): PipelineBuilder<TClients, TDb, LookupJoinedFor<TClients, TDb, TDoc, F, A, O>> {\n return this.derive<LookupJoinedFor<TClients, TDb, TDoc, F, A, O>>({\n $lookup: this.evalLookup(spec),\n });\n }\n\n facet<const F extends FacetSpec<TClients, TDb, TDoc>>(\n facets: F,\n ): PipelineBuilder<TClients, TDb, FacetOutput<TClients, TDb, TDoc, F>> {\n return this.derive<FacetOutput<TClients, TDb, TDoc, F>>({ $facet: this.evalFacets(facets) });\n }\n\n /* ------------------------------ terminals ---------------------------- */\n\n /** Run the pipeline and return every output document. */\n toArray(): Promise<TDoc[]> {\n const run = (r: ResolvedQueryOptions) =>\n this.deps\n .coll()\n .aggregate<TDoc>(this.stages, this.deps.mergeDriver(r.driverOpts, r.sdk))\n .toArray();\n if (this.deps.cachedAggregate) {\n return this.deps.cachedAggregate<string, TDoc[]>({\n collection: this.deps.logical,\n opName: 'mongo.pipeline',\n pipeline: this.stages,\n ...(this.deps.options !== undefined ? { options: this.deps.options } : {}),\n execute: run,\n });\n }\n return defineCrudOp(\n this.deps.crudDeps,\n this.deps.logical,\n 'mongo.pipeline',\n run,\n this.deps.options,\n false,\n { pipeline: this.stages },\n );\n }\n\n /** Run the pipeline and return the first output document (or null). */\n async first(): Promise<TDoc | null> {\n const run = async (r: ResolvedQueryOptions) => {\n const cursor = this.deps\n .coll()\n .aggregate<TDoc>(this.stages, this.deps.mergeDriver(r.driverOpts, r.sdk));\n try {\n return await cursor.tryNext();\n } finally {\n await cursor.close();\n }\n };\n // Distinct op name so `first()` never shares a cache entry with\n // `toArray()` on the same pipeline (they would collide on the key).\n if (this.deps.cachedAggregate) {\n return this.deps.cachedAggregate<string, TDoc | null>({\n collection: this.deps.logical,\n opName: 'mongo.pipeline.first',\n pipeline: this.stages,\n ...(this.deps.options !== undefined ? { options: this.deps.options } : {}),\n execute: run,\n });\n }\n return defineCrudOp(\n this.deps.crudDeps,\n this.deps.logical,\n 'mongo.pipeline.first',\n run,\n this.deps.options,\n false,\n { pipeline: this.stages },\n );\n }\n\n /** Streaming cursor (raw driver cursor; no retry / trace). */\n cursor(): AggregationCursor<TDoc> {\n return this.deps.coll().aggregate<TDoc>(this.stages, this.deps.options as AggregateOptions);\n }\n\n /* ------------------------------ internals ---------------------------- */\n\n private derive<NewDoc extends Document>(stage: Document): PipelineBuilder<TClients, TDb, NewDoc> {\n return new PipelineBuilder<TClients, TDb, NewDoc>(this.deps, [...this.stages, stage]);\n }\n\n private evalLookup(spec: Record<string, unknown>): Document {\n const { pipeline, ...rest } = spec;\n if (typeof pipeline === 'function') {\n const sub = new PipelineBuilder<any, any, Document>(this.deps, []);\n const result = (pipeline as (s: PipelineBuilder<any, any, Document>) => unknown)(sub);\n return { ...rest, pipeline: normalizeSubPipeline(result, '$lookup') };\n }\n return spec as Document;\n }\n\n private evalFacets(facets: Record<string, unknown>): Record<string, Document[]> {\n const out: Record<string, Document[]> = {};\n for (const [name, branch] of Object.entries(facets)) {\n if (typeof branch === 'function') {\n const sub = new PipelineBuilder<any, any, any>(this.deps, []);\n const result = (branch as (s: PipelineBuilder<any, any, any>) => unknown)(sub);\n out[name] = normalizeSubPipeline(result, `$facet.${name}`);\n } else {\n out[name] = branch as Document[];\n }\n }\n return out;\n }\n}\n\n/**\n * Normalize a sub-pipeline callback result into a raw `Document[]`.\n *\n * Sub-pipelines may be written as a CHAINED builder (`(o) => o.match(...).project(...)`)\n * or a raw array of stages. A common footgun is the array form where each element is\n * itself a builder result — `[o.match(...), o.project(...)]` — which silently produces\n * garbage stages and fails in Mongo with \"must contain exactly one field\" (code 40323).\n * We detect and reject that eagerly with a descriptive error.\n */\nexport const normalizeSubPipeline = (result: unknown, where: string): Document[] => {\n if (Array.isArray(result) && result.some((s) => s instanceof PipelineBuilder)) {\n throw new TypeError(\n `aggregation sub-pipeline (${where}) must be written as a chained builder — e.g. ` +\n '`(o) => o.match(...).project(...)` — not as an array of builder results like ' +\n '`[o.match(...), o.project(...)]` (each element is a builder, not a stage).',\n );\n }\n return result instanceof PipelineBuilder ? result.raw() : (result as Document[]);\n};\n\n/**\n * Create a non-executable, stage-only builder. Used to evaluate `$lookup` /\n * `$facet` sub-pipelines in the callback `aggregate()` API — the sub-pipeline\n * is only ever read via `.raw()`, never executed.\n */\nexport const stageBuilder = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n TDoc extends Document,\n>(): PipelineBuilder<TClients, TDb, TDoc> =>\n new PipelineBuilder<TClients, TDb, TDoc>({\n logical: '',\n coll: () => {\n throw new Error('stage-only pipeline builders cannot be executed');\n },\n crudDeps: {\n trace: () => Promise.reject(new Error('stage-only pipeline builders cannot be executed')),\n meta: () => ({ collection: '', physicalCollection: '', db: '', op: '' }),\n },\n mergeDriver: () => ({}),\n });\n","import type { Document } from 'mongodb';\nimport type { FilterInput } from '../shared/filter-types.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../types.ts';\nimport { normalizeSubPipeline, type PipelineBuilder, stageBuilder } from './pipeline-builder.ts';\nimport type {\n ForeignDocOf,\n GeoNearSpec,\n GroupSpec,\n LookupSpecFor,\n Projection,\n SortKeys,\n UnwindSpec,\n} from './pipeline-types.ts';\n\n/**\n * Typed aggregation-stage builder for the `db.aggregate(collection, (stages) =>\n * [...])` callback API. Each stage is validated against the source document\n * (`match` fields autocomplete and typo'd fields are compile errors), `$lookup`\n * sub-pipelines are scoped to the related collection, and `$facet` branches get\n * their own typed sub-builder. For inferred result types use the chained\n * `db.pipeline()` builder instead (`src/service/pipeline-builder.ts`).\n */\nexport interface AggregationStages<\n TDoc extends Document = Document,\n TClients extends DbClientsDefinition = DbClientsDefinition,\n TDb extends ExtractDbNames<TClients> = ExtractDbNames<TClients>,\n> {\n match(filter: FilterInput<TDoc>): { $match: FilterInput<TDoc> };\n project(fields: Projection<TDoc>): { $project: Projection<TDoc> };\n addFields(fields: Projection<TDoc>): { $addFields: Projection<TDoc> };\n set(fields: Projection<TDoc>): { $set: Projection<TDoc> };\n unset(fields: string | string[]): { $unset: string | string[] };\n sort(sort: SortKeys<TDoc>): { $sort: SortKeys<TDoc> };\n limit(n: number): { $limit: number };\n skip(n: number): { $skip: number };\n count(field: string): { $count: string };\n group(group: GroupSpec<TDoc>): { $group: GroupSpec<TDoc> };\n /**\n * `$geoNear` — requires a `2dsphere`/`2d` index and MUST be the first stage\n * (throws otherwise).\n */\n geoNear(spec: GeoNearSpec): { $geoNear: GeoNearSpec };\n lookup<\n const F extends ExtractCollectionNames<TClients, TDb>,\n const A extends string,\n const O extends Document = ForeignDocOf<TClients, TDb, F>,\n >(\n params: LookupSpecFor<TClients, TDb, TDoc, F> & {\n as: A;\n pipeline?:\n | Document[]\n | ((\n sub: PipelineBuilder<TClients, TDb, ForeignDocOf<TClients, TDb, F>>,\n ) => PipelineBuilder<TClients, TDb, O> | Document[]);\n },\n ): { $lookup: Document };\n facet(\n facets: Record<\n string,\n Document[] | ((stages: AggregationStages<TDoc, TClients, TDb>) => Document[])\n >,\n ): { $facet: Record<string, Document[]> };\n unwind(path: UnwindSpec): { $unwind: UnwindSpec };\n fill(params: Document): { $fill: Document };\n bucket(params: Document): { $bucket: Document };\n bucketAuto(params: Document): { $bucketAuto: Document };\n densify(params: Document): { $densify: Document };\n}\n\nexport const buildAggregationStages = <\n TDoc extends Document = Document,\n TClients extends DbClientsDefinition = DbClientsDefinition,\n TDb extends ExtractDbNames<TClients> = ExtractDbNames<TClients>,\n>(): AggregationStages<TDoc, TClients, TDb> => {\n // Tracks emitted stages so `$geoNear` (first-stage-only) can be guarded.\n let emitted = 0;\n const mark = <T>(stage: T): T => {\n emitted++;\n return stage;\n };\n return {\n match: (filter) => mark({ $match: filter }),\n project: (fields) => mark({ $project: fields }),\n addFields: (fields) => mark({ $addFields: fields }),\n set: (fields) => mark({ $set: fields }),\n unset: (fields) => mark({ $unset: fields }),\n sort: (sort) => mark({ $sort: sort }),\n limit: (n) => mark({ $limit: n }),\n skip: (n) => mark({ $skip: n }),\n count: (field) => mark({ $count: field }),\n group: (group) => mark({ $group: group }),\n lookup: <\n const F extends ExtractCollectionNames<TClients, TDb>,\n const A extends string,\n const O extends Document = ForeignDocOf<TClients, TDb, F>,\n >(\n params: LookupSpecFor<TClients, TDb, TDoc, F> & {\n as: A;\n pipeline?:\n | Document[]\n | ((\n sub: PipelineBuilder<TClients, TDb, ForeignDocOf<TClients, TDb, F>>,\n ) => PipelineBuilder<TClients, TDb, O> | Document[]);\n },\n ): { $lookup: Document } => {\n const { pipeline, ...rest } = params;\n if (typeof pipeline === 'function') {\n const sub = stageBuilder<TClients, TDb, ForeignDocOf<TClients, TDb, F>>();\n const result = (pipeline as (s: PipelineBuilder<TClients, TDb, any>) => unknown)(sub);\n return mark({\n $lookup: {\n ...rest,\n pipeline: normalizeSubPipeline(result, '$lookup'),\n },\n });\n }\n return mark({ $lookup: params });\n },\n facet: (facets) => {\n const out: Record<string, Document[]> = {};\n for (const [name, branch] of Object.entries(facets)) {\n out[name] =\n typeof branch === 'function'\n ? (branch as (stages: AggregationStages<TDoc, TClients, TDb>) => Document[])(\n buildAggregationStages<TDoc, TClients, TDb>(),\n )\n : branch;\n }\n return mark({ $facet: out });\n },\n unwind: (path) => mark({ $unwind: path }),\n fill: (params) => mark({ $fill: params }),\n bucket: (params) => mark({ $bucket: params }),\n bucketAuto: (params) => mark({ $bucketAuto: params }),\n densify: (params) => mark({ $densify: params }),\n geoNear: (spec) => {\n if (emitted > 0) {\n throw new Error('aggregate.geoNear(): $geoNear must be the first pipeline stage');\n }\n return mark({ $geoNear: spec });\n },\n };\n};\n","/**\n * Low-level + typed-pipeline aggregation ops: `aggregate` (callback stage API,\n * returns a live cursor) and `pipeline` (the fully type-safe chained\n * `PipelineBuilder`). Both funnel through the shared op pipeline.\n */\nimport type { AggregateOptions, AggregationCursor, Document } from 'mongodb';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport { type AggregationStages, buildAggregationStages } from '../aggregation-stages.ts';\nimport type { CrudOpDeps } from '../crud-op.ts';\nimport { defineCrudOp } from '../crud-op.ts';\nimport { PipelineBuilder } from '../pipeline-builder.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type { AggregationCtx, AggregationDocOf } from './types.ts';\n\n/** Build `aggregate` + `pipeline` from the shared aggregation context. */\nexport const makeAggregateOps = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: AggregationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = AggregationDocOf<TClients, TDb, X>;\n\n const { deps, coll, mergeAggOptions, cachedAggregate } = ctx;\n\n /** Low-level aggregate: returns a live cursor wrapped in the op pipeline. */\n const aggregate = async <X extends C, TResult extends Document = Document>(\n collection: X,\n pipelineBuilder: (stages: AggregationStages<DocOf2<X>, TClients, TDb>) => Document[],\n options?: AggregateOptions & QueryOptions,\n ): Promise<AggregationCursor<TResult>> => {\n const stages = buildAggregationStages<DocOf2<X>, TClients, TDb>();\n const pipeline = pipelineBuilder(stages);\n return defineCrudOp(\n deps,\n collection,\n 'mongo.aggregate',\n (r) => coll(collection).aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk)),\n options,\n false,\n { pipeline },\n );\n };\n\n /**\n * Fully type-safe, chainable pipeline builder. Each stage is typed against\n * the current document shape, `$lookup` sub-pipelines are scoped to the\n * related collection, and `$facet` branches get typed sub-builders — the\n * result type of `.toArray()` / `.first()` is inferred through the chain.\n */\n const pipeline = <const X extends C>(\n collection: X,\n options?: AggregateOptions & QueryOptions,\n ): PipelineBuilder<TClients, TDb, DocOf2<X>> =>\n new PipelineBuilder<TClients, TDb, DocOf2<X>>({\n logical: collection,\n coll: () => coll(collection),\n crudDeps: deps as unknown as CrudOpDeps<string>,\n mergeDriver: mergeAggOptions,\n ...(options !== undefined ? { options } : {}),\n cachedAggregate,\n });\n\n return { aggregate, pipeline };\n};\n","/**\n * Aggregation helpers shared by every op: `mergeAggOptions` (merge driver +\n * SDK options into a full `AggregateOptions`, forwarding `batchSize`), the\n * `DATE_PART_FORMATS` lookup for date-bucket `$dateToString` formats, and the\n * cache plumbing — `collectAggSources` (which source collections a pipeline\n * reads, for invalidation) and `isCacheablePipeline` (skip caching for\n * write/non-deterministic stages).\n */\nimport type { AggregateOptions, Document } from 'mongodb';\nimport type { AggregationSdkOptions, DateRangeConfig } from './types.ts';\n\n/** Merge resolved SDK options into the driver's aggregate options. */\nexport const mergeAggOptions = (\n driverOpts: Record<string, unknown>,\n sdk: AggregationSdkOptions,\n): AggregateOptions => ({\n ...(driverOpts as AggregateOptions),\n ...(sdk.session !== undefined ? { session: sdk.session } : {}),\n ...(sdk.maxTimeMS !== undefined ? { maxTimeMS: sdk.maxTimeMS } : {}),\n ...(sdk.hint !== undefined ? { hint: sdk.hint } : {}),\n ...(sdk.batchSize !== undefined ? { batchSize: sdk.batchSize } : {}),\n});\n\n/** `$dateToString` format per granularity for `dateRangeAnalysis`. */\nexport const DATE_PART_FORMATS: Record<NonNullable<DateRangeConfig['granularity']>, string> = {\n hour: '%Y-%m-%dT%H',\n day: '%Y-%m-%d',\n week: '%Y-W%V',\n month: '%Y-%m',\n year: '%Y',\n};\n\n/**\n * Collect every SOURCE collection an aggregation pipeline reads from, so cached\n * results can be invalidated when ANY of them changes. Starts with the primary\n * collection + any additional logical sources the op knows about (e.g.\n * `lookupJoin`'s `fromCollection`s), then walks the pipeline for:\n *\n * - `$lookup.from` (recursing into `$lookup.pipeline`)\n * - `$unionWith.coll` (recursing into `$unionWith.pipeline`)\n * - `$facet` branches (recursing into each branch's stages)\n *\n * The returned names are resolved to physical collection keys by the caller\n * (`resolve(logical)` — a known logical name — else treated as an already\n * physical name, which is what `lookupJoin` emits).\n */\nexport const collectAggSources = (\n primaryLogical: string,\n pipeline: Document[],\n extraLogical: string[] = [],\n): string[] => {\n const sources = new Set<string>([primaryLogical, ...extraLogical]);\n const visit = (stages: unknown): void => {\n if (!Array.isArray(stages)) return;\n for (const stage of stages) {\n if (!stage || typeof stage !== 'object') continue;\n const s = stage as Record<string, unknown>;\n const lookup = s.$lookup as Record<string, unknown> | undefined;\n if (lookup && typeof lookup === 'object') {\n if (typeof lookup.from === 'string') sources.add(lookup.from);\n if (Array.isArray(lookup.pipeline)) visit(lookup.pipeline);\n }\n const union = s.$unionWith as Record<string, unknown> | undefined;\n if (union && typeof union === 'object') {\n if (typeof union.coll === 'string') sources.add(union.coll);\n if (Array.isArray(union.pipeline)) visit(union.pipeline);\n }\n const facet = s.$facet as Record<string, unknown> | undefined;\n if (facet && typeof facet === 'object') {\n for (const branch of Object.values(facet)) visit(branch); // each branch is a stage list\n }\n }\n };\n visit(pipeline);\n return [...sources];\n};\n\n/**\n * Whether an aggregation pipeline is safe to cache. Results are NOT cached when\n * the pipeline writes (`$out` / `$merge`) or is non-deterministic (`$sample`).\n * Non-deterministic expressions beyond `$sample` (`$rand`, `$function`) are not\n * auto-detected — callers should opt out per op with `{ cache: false }`. The\n * check recurses into `$lookup.pipeline` and `$facet` branches.\n */\nexport const isCacheablePipeline = (pipeline: Document[]): boolean => {\n for (const stage of pipeline) {\n if (!stage || typeof stage !== 'object') continue;\n if ('$out' in stage || '$merge' in stage || '$sample' in stage) return false;\n const s = stage as Record<string, unknown>;\n const lookup = s.$lookup as { pipeline?: Document[] } | undefined;\n if (lookup && Array.isArray(lookup.pipeline) && !isCacheablePipeline(lookup.pipeline)) {\n return false;\n }\n const facet = s.$facet as Record<string, unknown> | undefined;\n if (facet && typeof facet === 'object') {\n for (const branch of Object.values(facet)) {\n if (Array.isArray(branch) && !isCacheablePipeline(branch)) return false;\n }\n }\n }\n return true;\n};\n","/**\n * Cached-aggregation read pipeline — the aggregation analog of the CRUD read\n * path (`crud/context.ts` `read()`): write-through `QueryCache` + in-flight\n * dedup for MATERIALIZED aggregation results.\n *\n * Aggregation results are derived documents, so schema-drift checking is NOT\n * applied here (drift is for raw reads). Caching is skipped when:\n * - the service has no cache (`perf:false` / `cache:null`) or the per-op\n * `cache:false` bypass is set;\n * - a session is present (transactional reads must hit the DB);\n * - the pipeline is not cacheable — `$out`/`$merge` writes or `$sample`\n * non-determinism (see `isCacheablePipeline`).\n *\n * Keys are db-namespaced by the PRIMARY collection; entries are additionally\n * registered under EVERY source collection (see `collectAggSources`) so a write\n * to ANY source invalidates them — this is what keeps `$lookup`/`$unionWith`\n * joins correct under write-through invalidation and `cacheWatch`.\n *\n * `aggregate()` (live cursor) and `pipeline().cursor()` are NOT cached — they\n * stream; use `pipeline().toArray()` / `.first()` for cached materialization.\n */\nimport type { AggregateOptions, Db, Document } from 'mongodb';\nimport type { InFlight } from '../../cache/in-flight.ts';\nimport { cacheCollectionKey, type QueryCache } from '../../cache/query-cache.ts';\nimport { stableHash } from '../../utils/hash.ts';\nimport { defineCrudOp } from '../crud-op.ts';\nimport type { OpDeps } from '../op-deps.ts';\nimport {\n type QueryOptions,\n type ResolvedQueryOptions,\n resolveQueryOptions,\n} from '../query-options.ts';\nimport { collectAggSources, isCacheablePipeline } from './helpers.ts';\n\n/**\n * The context the cached runner needs. Both the aggregation ops and the\n * `$facet` pagination strategy satisfy it structurally (their `opts` expose the\n * shared `cache` / `dedupeReads` / `inFlight` knobs).\n */\nexport type CachedAggregateCtx<C extends string> = {\n client: Db;\n deps: OpDeps<C>;\n opts: {\n cache?: QueryCache;\n dedupeReads: boolean;\n inFlight?: InFlight;\n cacheNamespace?: string;\n };\n resolve: (logical: string) => string;\n};\n\n/** Build the cached-aggregation runner from a collection-set-generic context. */\nexport const createCachedAggregate = <C extends string>(ctx: CachedAggregateCtx<C>) => {\n const { client, deps, opts, resolve } = ctx;\n const cache = opts.cache;\n\n return async <X extends string, T>(input: {\n collection: X;\n opName: string;\n pipeline: Document[];\n options?: AggregateOptions & QueryOptions;\n /** Additional LOGICAL source collections (e.g. `lookupJoin` fromCollections). */\n sources?: string[];\n execute: (resolved: ResolvedQueryOptions) => Promise<T>;\n }): Promise<T> => {\n const { collection: collectionName, opName, pipeline, options, sources = [], execute } = input;\n // `collectionName` is a known logical collection at the call site; the\n // widened `X extends string` keeps this assignable to `CachedAggregate`.\n const collection = collectionName as unknown as C;\n const physical = resolve(String(collection));\n const resolved = resolveQueryOptions(options);\n const noSession = !resolved.sdk.session;\n const useCache =\n cache !== undefined && noSession && resolved.cache !== false && isCacheablePipeline(pipeline);\n const shouldDedupe =\n resolved.dedupe !== false &&\n (resolved.dedupe === true || (opts.dedupeReads === true && noSession)) &&\n opts.inFlight !== undefined;\n\n // Keep the trace + transient-retry wrapper identical to today's path, but\n // record the pipeline as what-was-sent so the debugbar shows the full\n // aggregation (this covers `paginateFlexible`'s `$facet` too).\n const runDriver = (): Promise<T> =>\n defineCrudOp(deps, collection, opName, execute, options, false, { pipeline });\n\n // Only hash when caching (noSession is guaranteed) — a live session would\n // not serialize cleanly.\n const key = useCache\n ? cache!.key(\n cacheCollectionKey(client.databaseName, physical, opts.cacheNamespace),\n stableHash([opName, pipeline, options]),\n )\n : undefined;\n\n // Resolve every source collection → db-namespaced physical key, lazily (only\n // on a cache miss, so disabled caches pay nothing). Known logical names\n // resolve via `resolve()`; already-physical names (raw stages, `lookupJoin`)\n // pass through (a `resolve()` call on them would throw \"Unknown collection\").\n const toSourceKeys = () =>\n collectAggSources(String(collection), pipeline, sources).map((name) => {\n try {\n return cacheCollectionKey(client.databaseName, resolve(name), opts.cacheNamespace);\n } catch {\n return cacheCollectionKey(client.databaseName, name, opts.cacheNamespace);\n }\n });\n\n const runOnce = (): Promise<T> => {\n if (useCache && key) {\n // Capture the version of EVERY source collection before fetching so a\n // write to any of them mid-flight can never be hidden by a late set.\n const sourceKeys = toSourceKeys();\n const primaryKey = cacheCollectionKey(client.databaseName, physical, opts.cacheNamespace);\n const versions: Record<string, number> = { [primaryKey]: cache!.versionOf(primaryKey) };\n for (const col of sourceKeys) {\n if (!(col in versions)) versions[col] = cache!.versionOf(col);\n }\n const hit = cache!.get(key) as T | undefined;\n if (hit !== undefined) return Promise.resolve(hit);\n return runDriver().then((value) => {\n cache!.set(key, value, undefined, sourceKeys, versions);\n return value;\n });\n }\n return runDriver();\n };\n\n if (shouldDedupe) {\n // Version-scoped like the CRUD read path: a post-invalidation reader must\n // not join a pre-invalidation in-flight aggregation.\n const primaryKey = cacheCollectionKey(client.databaseName, physical, opts.cacheNamespace);\n const gen =\n cache !== undefined\n ? toSourceKeys()\n .map((source) => `${source}:${cache.versionOf(source)}`)\n .join('|')\n : '';\n const dedupeKey = `${primaryKey}|${gen}|${opName}|${stableHash([pipeline, options])}`;\n return await opts.inFlight!.run(dedupeKey, runOnce);\n }\n return await runOnce();\n };\n};\n","/**\n * Grouping aggregation ops: `groupBy` (bucket by key with accumulators) and\n * `dateRangeAnalysis` (bucket a date field by hour/day/week/month/year). Both\n * build a `$group` pipeline and run it through the shared op pipeline.\n */\nimport type { AggregateOptions, Document } from 'mongodb';\nimport { BadRequest } from '../../errors/index.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport { DATE_PART_FORMATS } from './helpers.ts';\nimport type {\n AggregationCtx,\n AggregationDocOf,\n DateRangeConfig,\n GroupByConfig,\n PipelineCustomization,\n} from './types.ts';\n\n/** Build `groupBy` + `dateRangeAnalysis` from the shared aggregation context. */\nexport const makeGroupOps = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: AggregationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = AggregationDocOf<TClients, TDb, X>;\n\n const { coll, mergeAggOptions, cachedAggregate } = ctx;\n\n /** Group documents by a key with optional accumulators/sort/limit (e.g. revenue per status). */\n const groupBy = async <X extends C, TResult extends Document = Document>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n config: GroupByConfig,\n customization: PipelineCustomization = {},\n options?: AggregateOptions & QueryOptions,\n ): Promise<TResult[]> => {\n if (config.limit !== undefined && (!Number.isFinite(config.limit) || config.limit < 0)) {\n throw new BadRequest('groupBy: `limit` must be a non-negative finite number');\n }\n const pipeline: Document[] = [\n ...(customization.prePipeline ?? []),\n { $match: baseFilter },\n { $group: { _id: config.groupBy, ...(config.accumulate ?? {}) } },\n ...(config.sort && Object.keys(config.sort).length > 0 ? [{ $sort: config.sort }] : []),\n ...(config.limit !== undefined ? [{ $limit: config.limit }] : []),\n ...(customization.postPipeline ?? []),\n ];\n return cachedAggregate<X, TResult[]>({\n collection,\n opName: 'mongo.groupBy',\n pipeline,\n ...(options !== undefined ? { options } : {}),\n execute: (r) =>\n coll(collection)\n .aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray(),\n });\n };\n\n /** Aggregate a metric over date buckets (hour/day/week/month/year) within a range. */\n const dateRangeAnalysis = async <X extends C, TResult extends Document = Document>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n dateConfig: DateRangeConfig,\n analysisConfig: {\n accumulate?: Record<string, unknown>;\n sort?: Record<string, 1 | -1>;\n limit?: number;\n } = {},\n customization: PipelineCustomization = {},\n options?: AggregateOptions & QueryOptions,\n ): Promise<TResult[]> => {\n if (\n analysisConfig.limit !== undefined &&\n (!Number.isFinite(analysisConfig.limit) || analysisConfig.limit < 0)\n ) {\n throw new BadRequest('dateRangeAnalysis: `limit` must be a non-negative finite number');\n }\n const granularity = dateConfig.granularity ?? 'day';\n const format = DATE_PART_FORMATS[granularity];\n const datePart = {\n $dateToString: { format, date: `$${dateConfig.dateField}` },\n };\n const pipeline: Document[] = [\n ...(customization.prePipeline ?? []),\n {\n $match: {\n ...baseFilter,\n [dateConfig.dateField]: { $gte: dateConfig.startDate, $lte: dateConfig.endDate },\n },\n },\n { $group: { _id: datePart, ...(analysisConfig.accumulate ?? {}) } },\n ...(analysisConfig.sort && Object.keys(analysisConfig.sort).length > 0\n ? [{ $sort: analysisConfig.sort }]\n : []),\n ...(analysisConfig.limit !== undefined ? [{ $limit: analysisConfig.limit }] : []),\n ...(customization.postPipeline ?? []),\n ];\n return cachedAggregate<X, TResult[]>({\n collection,\n opName: 'mongo.dateRangeAnalysis',\n pipeline,\n ...(options !== undefined ? { options } : {}),\n execute: (r) =>\n coll(collection)\n .aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray(),\n });\n };\n\n return { groupBy, dateRangeAnalysis };\n};\n","/**\n * Join aggregation op — `lookupJoin`: `$lookup` one or more related\n * (logical) collections, optionally `$unwind`-ing the joined arrays (preserving\n * nulls). Single-collection hops built declaratively from `LookupConfig[]`.\n */\nimport type { AggregateOptions, Document } from 'mongodb';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type {\n AggregationCtx,\n AggregationDocOf,\n LookupConfig,\n PipelineCustomization,\n} from './types.ts';\n\n/** Build `lookupJoin` from the shared aggregation context. */\nexport const makeLookupJoinOp = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: AggregationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = AggregationDocOf<TClients, TDb, X>;\n\n const { coll, mergeAggOptions, resolve, cachedAggregate } = ctx;\n\n /** Join related docs via `$lookup` + optional `$unwind` (single collection hop). */\n const lookupJoin = async <X extends C, TResult extends Document = DocOf2<X>>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n lookups: LookupConfig[],\n customization: PipelineCustomization = {},\n options?: AggregateOptions & QueryOptions,\n ): Promise<TResult[]> => {\n const pipeline: Document[] = [\n ...(customization.prePipeline ?? []),\n { $match: baseFilter },\n ...lookups.map((lookup) => ({\n $lookup: {\n from: resolve(lookup.fromCollection),\n localField: lookup.localField,\n foreignField: lookup.foreignField,\n as: lookup.as,\n ...(lookup.pipeline ? { pipeline: lookup.pipeline } : {}),\n },\n })),\n ...lookups\n .filter((lookup) => lookup.unwindSingle)\n .map((lookup) => ({\n $unwind: { path: `$${lookup.as}`, preserveNullAndEmptyArrays: true },\n })),\n ...(customization.postPipeline ?? []),\n ];\n return cachedAggregate<X, TResult[]>({\n collection,\n opName: 'mongo.lookupJoin',\n pipeline,\n ...(options !== undefined ? { options } : {}),\n // Writes to any joined collection must invalidate the cached join.\n sources: lookups.map((l) => l.fromCollection),\n execute: (r) =>\n coll(collection)\n .aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray(),\n });\n };\n\n return { lookupJoin };\n};\n","import { BadRequest } from '../errors/index.ts';\n\nexport interface CrudListQuery {\n page?: number;\n limit?: number;\n}\n\nexport interface NormalizedPagination {\n page: number;\n limit: number;\n offset: number;\n}\n\n/**\n * Normalize + validate page/limit. Pure — no DB knowledge.\n * - `page` is floored to >= 1\n * - `limit` must be within [1, maxLimit] or a `BadRequest` is thrown\n */\nexport const normalizePageLimit = (\n query: CrudListQuery,\n maxLimit: number,\n defaults: { page?: number; limit?: number } = {},\n): NormalizedPagination => {\n const rawPage = query.page ?? defaults.page ?? 1;\n const limit = query.limit ?? defaults.limit ?? 10;\n\n // Reject NaN / Infinity / non-numbers up front — `Math.floor(NaN)` would\n // otherwise flow into `$skip: NaN` as an obscure driver error.\n if (typeof rawPage !== 'number' || !Number.isFinite(rawPage)) {\n throw new BadRequest('page must be a finite number');\n }\n if (typeof limit !== 'number' || !Number.isFinite(limit)) {\n throw new BadRequest('limit must be a finite number');\n }\n if (limit < 1) throw new BadRequest('limit must be >= 1');\n if (limit > maxLimit) throw new BadRequest(`limit ${limit} exceeds maxLimit ${maxLimit}`);\n\n const page = Math.max(1, Math.floor(rawPage));\n return { page, limit, offset: (page - 1) * limit };\n};\n","export interface AggregationMeta {\n executionTimeMs?: number;\n indexesUsed?: string[];\n}\n\n/** Uniform pagination result shape (shared by all list/paginate/search ops). */\nexport interface PaginationResult<T> {\n data: T[];\n totalCount: number;\n hasNextPage: boolean;\n hasPrevPage: boolean;\n currentPage: number;\n totalPages: number;\n aggregationMeta?: AggregationMeta;\n}\n\nexport const buildPaginationResult = <T>(\n data: T[],\n totalCount: number,\n page: number,\n limit: number,\n): PaginationResult<T> => {\n const totalPages = totalCount === 0 ? 0 : Math.ceil(totalCount / limit);\n return {\n data,\n totalCount,\n hasNextPage: page < totalPages,\n hasPrevPage: page > 1,\n currentPage: page,\n totalPages,\n };\n};\n","import type { Document, Filter } from 'mongodb';\n\nexport interface SearchConfig {\n /** Fields to search across. */\n searchFields: string[];\n /** Search term. */\n searchTerm: string;\n /** Loose per-character matching (`$regex` mode only). */\n fuzzy?: boolean;\n /** Case sensitivity (`$text` mode; `$regex` mode uses this too). */\n caseSensitive?: boolean;\n /** true → `$regex` search; false (default) → `$text` search. */\n useRegex?: boolean;\n /** `$text` search language (defaults to the server's default). */\n language?: string;\n /** `$text` diacritic sensitivity (default false → insensitive). */\n diacriticSensitive?: boolean;\n /**\n * When true, `textSearch` sorts by `searchScore` (textScore meta) instead of\n * the caller's sort. `$text`-mode only.\n */\n sortByScore?: boolean;\n}\n\nconst escapeRegex = (value: string): string => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n/** Build `$regex` search stages with an optional fuzzy (loose) pattern. */\nexport const buildRegexSearchStages = <T extends Document>(\n baseFilter: Filter<T>,\n searchConfig: SearchConfig,\n): Document[] => {\n const { searchFields, searchTerm, fuzzy = false, caseSensitive = false } = searchConfig;\n const escaped = escapeRegex(searchTerm);\n const pattern = fuzzy ? escaped.split('').join('.*') : escaped;\n const $or = searchFields.map((field) => ({\n [field]: { $regex: pattern, $options: caseSensitive ? '' : 'i' },\n }));\n return [{ $match: { ...baseFilter, $or } as Filter<T> }];\n};\n\n/** Build `$text` search stages with a `searchScore` meta field. */\nexport const buildTextSearchStages = <T extends Document>(\n baseFilter: Filter<T>,\n searchConfig: SearchConfig,\n): Document[] => [\n {\n $match: {\n ...baseFilter,\n $text: {\n $search: searchConfig.searchTerm,\n ...(searchConfig.caseSensitive !== undefined && {\n $caseSensitive: searchConfig.caseSensitive,\n }),\n ...(searchConfig.language !== undefined && { $language: searchConfig.language }),\n ...(searchConfig.diacriticSensitive !== undefined && {\n $diacriticSensitive: searchConfig.diacriticSensitive,\n }),\n },\n } as Filter<T>,\n },\n { $addFields: { searchScore: { $meta: 'textScore' } } },\n];\n\n/** Pick the search strategy based on `useRegex`. */\nexport const buildSearchStages = <T extends Document>(\n baseFilter: Filter<T>,\n searchConfig: SearchConfig,\n): Document[] =>\n searchConfig.useRegex\n ? buildRegexSearchStages(baseFilter, searchConfig)\n : buildTextSearchStages(baseFilter, searchConfig);\n","/**\n * Text-search aggregation op — `textSearch`: `$regex` (fuzzy, per-field `$or`)\n * or `$text` (`$search`, `$caseSensitive`, `$language`, `$diacriticSensitive`),\n * with `$facet` pagination and optional score sorting. Uses the search-stage\n * builders from `./aggregation-pipeline.ts`.\n */\nimport type { AggregateOptions, Document, Filter } from 'mongodb';\nimport { DEFAULT_MAX_LIMIT } from '../../shared/constants.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport { normalizePageLimit } from '../../shared/pagination-math.ts';\nimport { buildPaginationResult, type PaginationResult } from '../../shared/pagination-result.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport { buildSearchStages, type SearchConfig } from '../aggregation-pipeline.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type {\n AggregationCtx,\n AggregationDocOf,\n PipelineCustomization,\n TextSearchPagination,\n} from './types.ts';\n\n/** Build `textSearch` from the shared aggregation context. */\nexport const makeTextSearchOp = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: AggregationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = AggregationDocOf<TClients, TDb, X>;\n\n const { coll, mergeAggOptions, cachedAggregate } = ctx;\n\n /** Full-text / regex search with `$facet` pagination and optional score-sorting. */\n const textSearch = async <X extends C>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n searchConfig: SearchConfig,\n paginationConfig: TextSearchPagination = {},\n customization: PipelineCustomization = {},\n options?: AggregateOptions & QueryOptions,\n ): Promise<PaginationResult<DocOf2<X> & { searchScore?: number }>> => {\n const normalized = normalizePageLimit(\n {\n ...(paginationConfig.page !== undefined ? { page: paginationConfig.page } : {}),\n ...(paginationConfig.limit !== undefined ? { limit: paginationConfig.limit } : {}),\n },\n paginationConfig.maxLimit ?? DEFAULT_MAX_LIMIT,\n );\n const searchStages = buildSearchStages(\n baseFilter as unknown as Filter<DocOf2<X>>,\n searchConfig,\n );\n const pipeline: Document[] = [\n ...(customization.prePipeline ?? []),\n ...searchStages,\n {\n $facet: {\n data: [\n ...(searchConfig.sortByScore\n ? [{ $sort: { searchScore: { $meta: 'textScore' } } }]\n : []),\n ...(paginationConfig.sort && Object.keys(paginationConfig.sort).length > 0\n ? [{ $sort: paginationConfig.sort }]\n : []),\n { $skip: normalized.offset },\n { $limit: normalized.limit },\n ...(customization.postPipeline ?? []),\n ],\n totalCount: [{ $count: 'count' }],\n },\n },\n ];\n return cachedAggregate<X, PaginationResult<DocOf2<X> & { searchScore?: number }>>({\n collection,\n opName: 'mongo.textSearch',\n pipeline,\n ...(options !== undefined ? { options } : {}),\n execute: async (r) => {\n const rows = await coll(collection)\n .aggregate(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray();\n const row = rows[0] as\n | {\n data?: Array<DocOf2<X> & { searchScore?: number }>;\n totalCount?: Array<{ count: number }>;\n }\n | undefined;\n const data = row?.data ?? [];\n const totalCount = row?.totalCount?.[0]?.count ?? 0;\n return buildPaginationResult(data, totalCount, normalized.page, normalized.limit);\n },\n });\n };\n\n return { textSearch };\n};\n","/**\n * Aggregation op factory — `makeAggregationOps`. Composes the aggregation op\n * groups into one set per database:\n *\n * - `./aggregate.ts` — `aggregate` (callback stage API) + `pipeline` (typed builder)\n * - `./group.ts` — `groupBy` + `dateRangeAnalysis`\n * - `./text-search.ts` — `textSearch`\n * - `./lookup-join.ts` — `lookupJoin`\n *\n * All share a context (`./types.ts`) and the merged-options/date-format\n * helpers (`./helpers.ts`) built here.\n */\nimport type { Db, Document } from 'mongodb';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { makeOpDeps } from '../op-deps.ts';\nimport { makeAggregateOps } from './aggregate.ts';\nimport { createCachedAggregate } from './cached-read.ts';\nimport { makeGroupOps } from './group.ts';\nimport { mergeAggOptions } from './helpers.ts';\nimport { makeLookupJoinOp } from './lookup-join.ts';\nimport { makeTextSearchOp } from './text-search.ts';\nimport type { AggregationCtx, AggregationOpsOptions } from './types.ts';\n\n/**\n * Aggregation ops for one database: `aggregate`, `pipeline`, `groupBy`,\n * `textSearch`, `dateRangeAnalysis`, `lookupJoin`. All collection-name first\n * and schema-typed. Materializing ops (`pipeline().toArray()/.first()`,\n * `groupBy`, `dateRangeAnalysis`, `textSearch`, `lookupJoin`) route through the\n * shared cached-aggregation runner (`cachedAggregate`) — write-through cache +\n * in-flight dedup, invalidated per source collection. `aggregate()` and\n * `pipeline().cursor()` stream live cursors and stay uncached.\n */\nexport const makeAggregationOps = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n client: Db,\n dbLabel: string,\n logger: LoggerLike,\n opts: AggregationOpsOptions,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n\n const resolve = opts.resolveCollectionName;\n const deps = makeOpDeps<C>(\n logger,\n dbLabel,\n resolve,\n opts.wrapMongoErrors === true,\n opts.debugQuery,\n );\n const coll = (collection: C) => client.collection<Document>(resolve(String(collection)));\n\n const ctx: AggregationCtx<TClients, TDb> = {\n client,\n dbLabel,\n logger,\n opts,\n resolve,\n deps,\n coll,\n mergeAggOptions,\n cachedAggregate: createCachedAggregate<C>({ client, deps, opts, resolve }),\n };\n\n return {\n ...makeAggregateOps<TClients, TDb>(ctx),\n ...makeGroupOps<TClients, TDb>(ctx),\n ...makeTextSearchOp<TClients, TDb>(ctx),\n ...makeLookupJoinOp<TClients, TDb>(ctx),\n };\n};\n\n// Re-export the public aggregation types so the folder barrel matches the old\n// single-module exports.\nexport type {\n AggregationOpsOptions,\n DateRangeConfig,\n GroupByConfig,\n LookupConfig,\n PipelineCustomization,\n} from './types.ts';\n","/**\n * Schema-default materialization for writes.\n *\n * The schema DSL lets fields carry a `.default(v)` (`flags.hasDefault` +\n * `flags.defaultValue`). Until this module existed those defaults were only\n * *declared* — validation allowed the field to be absent, but nothing ever\n * wrote the value, so stored documents silently lacked defaulted fields. The\n * ORM's own timestamp stamping had the same shape (absent → stamped at\n * insert), and defaults should behave the same: materialized at write time so\n * every stored document carries them.\n *\n * `applySchemaDefaults` fills missing keys (in place, recursively into nested\n * object fields) with a per-document deep clone of the declared default, so\n * no two documents ever share a mutable default reference.\n */\n\nimport type { Document } from 'mongodb';\nimport { cloneDeep } from '../utils/clone.ts';\nimport type { ObjectField } from './types.ts';\n\nconst cloneDefault = (value: unknown): unknown => cloneDeep(value);\n\n/**\n * Fill schema defaults into `doc` (in place). Only *absent* keys are written;\n * explicitly-provided values (including `undefined`, which the write pipeline\n * strips afterwards) are never overwritten. Nested object fields are recursed\n * into so their inner defaults materialize too.\n *\n * @param schema - The collection's declared schema (`ObjectField`), if any.\n * @param doc - Document being created or fully replaced.\n */\nexport const applySchemaDefaults = (schema: ObjectField | undefined, doc: Document): void => {\n if (!schema || doc === null || typeof doc !== 'object' || Array.isArray(doc)) return;\n\n for (const [key, prop] of Object.entries(schema.properties)) {\n if (key in doc && doc[key] !== undefined) {\n // Present value: recurse so nested defaults materialize around it.\n if (\n prop.kind === 'object' &&\n doc[key] !== null &&\n typeof doc[key] === 'object' &&\n !Array.isArray(doc[key])\n ) {\n applySchemaDefaults(prop, doc[key] as Document);\n }\n continue;\n }\n if (prop.flags.hasDefault) {\n doc[key] = cloneDefault(prop.flags.defaultValue);\n }\n }\n};\n","/**\n * `undefined`-value handling for write payloads.\n *\n * TypeScript signals \"absent\" with `undefined`, and object spreads commonly\n * leave optional fields as `undefined` (`{ ...(x ? { a: x } : {}) }` patterns).\n * The MongoDB driver serializes explicit `undefined` as `null`, which then\n * violates a strict `$jsonSchema` validator (string/date/objectId fields\n * reject `null`). Stripping `undefined` keys — never `null` — makes \"absent\"\n * behave as absent on the wire.\n */\n\n/** Strip `undefined` values from a document's own (top-level) keys, in place. */\nexport const stripUndefinedKeys = <T extends Record<string, unknown>>(doc: T): T => {\n for (const key of Object.keys(doc)) {\n if (doc[key] === undefined) {\n delete (doc as Record<string, unknown>)[key];\n }\n }\n return doc;\n};\n\n/**\n * Strip `undefined` values from an update payload: top-level plain-patch keys\n * AND nested values inside `$set` / `$setOnInsert` operator objects. Operator\n * forms beyond those two are left untouched (their semantics differ).\n */\nexport const stripUndefinedFromUpdate = <T>(update: T): T => {\n if (update === null || typeof update !== 'object') return update;\n const doc = update as Record<string, unknown>;\n\n for (const operator of ['$set', '$setOnInsert']) {\n const op = doc[operator];\n if (op !== null && typeof op === 'object' && !Array.isArray(op)) {\n const opDoc = op as Record<string, unknown>;\n for (const key of Object.keys(opDoc)) {\n if (opDoc[key] === undefined) delete opDoc[key];\n }\n }\n }\n\n for (const key of Object.keys(doc)) {\n if (doc[key] === undefined) delete doc[key];\n }\n return update;\n};\n","/**\n * Shared schema-drift checker for the read path.\n *\n * Checks freshly-fetched documents (the result of an actual DB round-trip,\n * not a cache hit) against their declared schema and either logs the drift\n * (`'report'` mode) or throws a typed `DomainError SCHEMA_DRIFT` (`'throw'`).\n * Detection-only — never mutates the documents.\n */\nimport type { Document } from 'mongodb';\nimport { DomainError } from '../errors/index.ts';\nimport type { ObjectField } from '../schema/types.ts';\nimport { type DriftMode, validateDoc } from '../schema/validate-doc/index.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\n\nexport interface DriftCheckerOptions {\n logger: LoggerLike;\n /** DB label for error/log context. */\n db: string;\n /** Effective drift mode for this read (already resolved from per-op + service). */\n drift: DriftMode;\n /** Resolve the declared schema for a logical collection. */\n getSchema?: (logical: string) => ObjectField | undefined;\n /** Projection-aware validation: ignore absent fields, but validate present values. */\n partial?: boolean;\n}\n\n/**\n * Validate `docs` against the collection schema and react per the drift mode.\n * No-op when `drift` is `'off'`, the collection has no schema, or the docs are\n * all conformant.\n */\nexport const checkDocsDrift = (\n options: DriftCheckerOptions,\n collection: string,\n op: string,\n docs: Document[],\n): void => {\n if (options.drift === 'off') return;\n const schema = options.getSchema?.(collection);\n if (!schema) return;\n for (const doc of docs) {\n const issues = validateDoc(schema, doc).filter(\n (issue) => options.partial !== true || issue.code !== 'missing',\n );\n if (issues.length === 0) continue;\n const detail = issues.map((i) => `${i.path}: ${i.message}`).join('; ');\n const extra = { collection, db: options.db, op, issues };\n if (options.drift === 'throw') {\n throw new DomainError(\n 'SCHEMA_DRIFT',\n `Document drifted from schema in \"${collection}\": ${detail}`,\n extra,\n );\n }\n options.logger.warn(extra, `[drift] ${collection} (${options.db}, ${op}): ${detail}`);\n }\n};\n","import type { Document, UpdateFilter } from 'mongodb';\nimport type { UpdateInput } from './update-types.ts';\n\n/** True when `update` uses `$`-operator syntax (vs a plain field patch). */\nexport const hasUpdateOperator = (update?: UpdateFilter<Record<string, unknown>>): boolean => {\n if (!update) return false;\n return Object.keys(update).some((key) => key.startsWith('$'));\n};\n\n/**\n * Normalize an update payload: a plain object (e.g. `{ name: 'x' }`) becomes\n * `{ $set: { name: 'x' } }`; documents already using `$` operators pass through\n * unchanged. Used by `upsert` / `bulkUpsert`.\n */\nexport const formatUpdateFilter = <T extends Document>(update: UpdateInput<T>): UpdateFilter<T> => {\n if (hasUpdateOperator(update as UpdateFilter<Record<string, unknown>>)) {\n return update as UpdateFilter<T>;\n }\n return { $set: update } as UpdateFilter<T>;\n};\n","/**\n * Shared CRUD context: the cross-cutting helpers every CRUD op group depends\n * on (collection resolution, tracing, retry plumbing, cache/dedup/drift read\n * pipeline, auto-timestamps, `select` normalization).\n *\n * `makeCrudOps` (see `./index.ts`) builds ONE context via `createCrudContext`\n * and hands it to the read / write / watch op-group factories, so the helpers\n * live in exactly one place instead of being duplicated per op. This module is\n * the dependency-injection seam of the CRUD layer.\n */\nimport {\n type Collection,\n type Db,\n type Document,\n type Filter,\n type FindOptions,\n ObjectId,\n} from 'mongodb';\nimport type { InFlight } from '../../cache/in-flight.ts';\nimport type { QueryCache } from '../../cache/query-cache.ts';\nimport { cacheCollectionKey } from '../../cache/query-cache.ts';\nimport { DomainError } from '../../errors/index.ts';\nimport type { HooksRegistry } from '../../hooks/hooks.ts';\nimport { withRetry } from '../../mongo-helpers.ts';\nimport { applySchemaDefaults } from '../../schema/apply-defaults.ts';\nimport type { ObjectField } from '../../schema/types.ts';\nimport { type DriftMode, validateDoc } from '../../schema/validate-doc/index.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport type {\n CollectionTimestamps,\n DbClientsDefinition,\n ExtractCollectionNames,\n ExtractCollectionType,\n ExtractDbNames,\n} from '../../types.ts';\nimport { stableHash } from '../../utils/hash.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { stripUndefinedFromUpdate, stripUndefinedKeys } from '../../utils/omit-undefined.ts';\nimport { defineCrudOp } from '../crud-op.ts';\nimport { checkDocsDrift } from '../drift.ts';\nimport { makeOpDeps } from '../op-deps.ts';\nimport {\n type QueryOptions,\n type ResolvedQueryOptions,\n resolveDriftMode,\n resolveQueryOptions,\n} from '../query-options.ts';\nimport type { DbOpMeta } from '../trace-db-op.ts';\nimport { formatUpdateFilter } from '../update-format.ts';\nimport type { UpdateInput } from '../update-types.ts';\n\nexport type ColNames<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> = ExtractCollectionNames<TClients, TDb>;\n\nexport type DocOf<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n C extends ColNames<TClients, TDb>,\n> = ExtractCollectionType<TClients, TDb, C>;\n\n/** Input accepted by insert ops: the doc without `_id`, or with an explicit `_id`. */\nexport type InsertInput<T> = Omit<T, '_id'> & { _id?: T extends { _id: infer I } ? I : never };\n\nexport type VersionedUpdateResult<T> =\n | { ok: true; doc: T }\n | { ok: false; reason: 'not_found' | 'version_conflict' };\n\n/**\n * Find-query options. Extends driver `FindOptions` + SDK `QueryOptions` with a\n * first-class `select` (field list) that is translated to a driver `projection`\n * so only the requested fields are transferred from the server.\n */\nexport type FindQueryOptions<T> = FindOptions &\n QueryOptions & {\n /** Project only the listed fields — pushed to the driver as `projection`. */\n select?: readonly (keyof T)[];\n };\n\n/** Per-collection auto-timestamp config (keyed by logical collection name). */\nexport type TimestampsByCollection = Record<string, CollectionTimestamps | undefined>;\n\nexport interface CrudOpsOptions {\n resolveCollectionName: (logical: string) => string;\n /** Stable, non-secret identity of the MongoDB deployment for shared caches. */\n cacheNamespace?: string;\n wrapMongoErrors?: boolean;\n debugQuery?: import('../trace-db-op.ts').DebugQuery | null;\n cache?: QueryCache;\n dedupeReads?: boolean;\n inFlight?: InFlight;\n hooks?: HooksRegistry;\n /** Auto-timestamp field names per collection (from the collection definition). */\n timestamps?: TimestampsByCollection;\n validateWrites?: boolean;\n /** Service-level schema-drift policy for reads (default `'report'`). */\n drift?: DriftMode;\n /** Resolve the declared schema for a logical collection (drift detection). */\n getSchema?: (logical: string) => ObjectField | undefined;\n}\n\n/**\n * Everything a CRUD op-group factory needs, bundled into one immutable object.\n * See `createCrudContext` for the wiring.\n */\nexport interface CrudContext<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> {\n client: Db;\n dbLabel: string;\n logger: LoggerLike;\n opts: CrudOpsOptions;\n /** Logical → physical collection name. */\n resolve: (logical: string) => string;\n /** Trace + optional error mapping for a single DB call. */\n trace: <T>(meta: DbOpMeta, fn: () => T | Promise<T>) => Promise<T>;\n /** Structured log metadata for a (collection, op). */\n meta: (collection: ColNames<TClients, TDb>, op: string) => DbOpMeta;\n /** Raw driver collection handle for a logical collection. */\n coll: <X extends ColNames<TClients, TDb>>(name: X) => Collection<DocOf<TClients, TDb, X>>;\n /** Narrow the strict public filter to the driver's loose `Filter<T>`. */\n toDriverFilter: <X extends ColNames<TClients, TDb>>(\n filter: FilterInput<DocOf<TClients, TDb, X>>,\n ) => Filter<DocOf<TClients, TDb, X>>;\n /** Op pipeline (resolve → trace → retry) for reads. */\n run: <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n options?: QueryOptions,\n /** What was sent to the DB — recorded in the debugbar as the span's params. */\n params?: unknown,\n ) => Promise<T>;\n /** Op pipeline for writes — transient errors retried only with `retryWrites: true`. */\n writeRun: <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n options?: QueryOptions,\n params?: unknown,\n ) => Promise<T>;\n /** Drop this collection's cached reads (DB-namespaced key). */\n invalidate: (collection: ColNames<TClients, TDb>) => void;\n /** Stamp `createdAt`/`updatedAt` onto a doc being created (in place, only when unset). */\n stampCreate: (collection: ColNames<TClients, TDb>, doc: Document) => void;\n /** Merge `updatedAt` into an update payload (plain patch or `$set` operator form). */\n stampUpdate: <X extends ColNames<TClients, TDb>>(\n collection: X,\n update: UpdateInput<DocOf<TClients, TDb, X>>,\n ) => UpdateInput<DocOf<TClients, TDb, X>>;\n /** Return a full replacement with `updatedAt` stamped. */\n stampReplace: (collection: ColNames<TClients, TDb>, doc: Document) => Document;\n validateWrite: (collection: ColNames<TClients, TDb>, doc: Document, generateId?: boolean) => void;\n /** Shared read pipeline: trace + retry, with opt-in cache and in-flight dedup. */\n read: <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n filter: FilterInput<DocOf<TClients, TDb, X>>,\n options: QueryOptions | undefined,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n shape?: 'one' | 'many' | 'none',\n /** Extra key discriminator (e.g. `distinct`'s field name). */\n keyExtra?: string,\n ) => Promise<T>;\n /** Translate `select` (field list) into a driver `projection`; strip `select`. */\n normalizeFindOptions: <T>(options: FindQueryOptions<T> | undefined) => FindOptions & QueryOptions;\n}\n\n/**\n * Build the CRUD shared context. All state is closure-local (no module-level\n * mutation) and handed to the op-group factories for composition.\n */\nexport const createCrudContext = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n client: Db,\n dbLabel: string,\n logger: LoggerLike,\n opts: CrudOpsOptions,\n): CrudContext<TClients, TDb> => {\n const resolve = opts.resolveCollectionName;\n const deps = makeOpDeps<ColNames<TClients, TDb>>(\n logger,\n dbLabel,\n resolve,\n opts.wrapMongoErrors === true,\n opts.debugQuery,\n );\n const coll = <X extends ColNames<TClients, TDb>>(name: X): Collection<DocOf<TClients, TDb, X>> =>\n client.collection<DocOf<TClients, TDb, X>>(resolve(String(name)));\n const toDriverFilter = <X extends ColNames<TClients, TDb>>(\n filter: FilterInput<DocOf<TClients, TDb, X>>,\n ): Filter<DocOf<TClients, TDb, X>> => filter as unknown as Filter<DocOf<TClients, TDb, X>>;\n const run = <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n options?: QueryOptions,\n params?: unknown,\n ): Promise<T> => defineCrudOp(deps, collection, opName, execute, options, false, params);\n\n /** Same as `run` but for write ops — transient errors are NOT auto-retried\n * unless the caller opts in via `QueryOptions.retryWrites` (at-least-once). */\n const writeRun = <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n options?: QueryOptions,\n params?: unknown,\n ): Promise<T> => defineCrudOp(deps, collection, opName, execute, options, true, params);\n\n const invalidate = (collection: ColNames<TClients, TDb>): void => {\n // Namespaced by DB so a write to one database never (in)validates another's\n // same-named collection in the shared cache.\n opts.cache?.invalidateByCollection(\n cacheCollectionKey(client.databaseName, resolve(String(collection)), opts.cacheNamespace),\n );\n };\n\n const timestampsFor = (collection: ColNames<TClients, TDb>): CollectionTimestamps | undefined =>\n opts.timestamps?.[String(collection)];\n\n /**\n * Normalize + stamp a doc being created (in place): schema defaults are\n * materialized first (absent defaulted fields get their declared value),\n * `undefined` keys are stripped (TS \"absent\" must not serialize to `null`\n * under a strict validator) and `createdAt`/`updatedAt` are set when unset.\n */\n const stampCreate = (collection: ColNames<TClients, TDb>, doc: Document): void => {\n applySchemaDefaults(opts.getSchema?.(String(collection)), doc);\n stripUndefinedKeys(doc);\n const ts = timestampsFor(collection);\n if (!ts) return;\n const now = new Date();\n if (ts.createdAt && doc[ts.createdAt] === undefined) doc[ts.createdAt] = now;\n if (ts.updatedAt && doc[ts.updatedAt] === undefined) doc[ts.updatedAt] = now;\n };\n\n /** Normalize + merge `updatedAt` into an update payload (plain patch or `$set` operator form). */\n const stampUpdate = <X extends ColNames<TClients, TDb>>(\n collection: X,\n update: UpdateInput<DocOf<TClients, TDb, X>>,\n ): UpdateInput<DocOf<TClients, TDb, X>> => {\n // `undefined` = absent, never `null` on the wire (see omit-undefined).\n stripUndefinedFromUpdate(update);\n // Always normalize plain patches into `$set` form (matches `formatUpdateFilter`).\n const formatted = formatUpdateFilter(update) as Document & { $set?: Document };\n const ts = timestampsFor(collection);\n if (ts?.updatedAt) {\n const $set = { ...(formatted.$set as Document | undefined), [ts.updatedAt]: new Date() };\n return { ...formatted, $set } as unknown as UpdateInput<DocOf<TClients, TDb, X>>;\n }\n return formatted as unknown as UpdateInput<DocOf<TClients, TDb, X>>;\n };\n\n /** Return a full replacement with `updatedAt` stamped (findOneAndReplace/replaceOne). */\n const stampReplace = (collection: ColNames<TClients, TDb>, doc: Document): Document => {\n applySchemaDefaults(opts.getSchema?.(String(collection)), doc);\n stripUndefinedKeys(doc);\n const ts = timestampsFor(collection);\n if (!ts?.updatedAt) return doc;\n return { ...doc, [ts.updatedAt]: new Date() };\n };\n\n const validateWrite = (\n collection: ColNames<TClients, TDb>,\n doc: Document,\n generateId = true,\n ): void => {\n if (opts.validateWrites === false) return;\n const schema = opts.getSchema?.(String(collection));\n if (!schema) return;\n if (generateId && doc._id === undefined && schema.properties._id?.kind === 'objectId') {\n doc._id = new ObjectId();\n }\n const issues = validateDoc(schema, doc).filter(\n (issue) => generateId || issue.path !== '_id' || issue.code !== 'missing',\n );\n if (issues.length > 0) {\n throw new DomainError('VALIDATION_FAILED', 'Document failed schema validation', {\n db: client.databaseName,\n collection: String(collection),\n ...(doc._id !== undefined ? { documentId: doc._id } : {}),\n fields: [...new Set(issues.map((issue) => issue.path))],\n issues,\n });\n }\n };\n\n /** Shared read pipeline: trace + retry, with opt-in cache and in-flight dedup. */\n const read = async <X extends ColNames<TClients, TDb>, T>(\n collection: X,\n opName: string,\n filter: FilterInput<DocOf<TClients, TDb, X>>,\n options: QueryOptions | undefined,\n execute: (resolved: ResolvedQueryOptions) => Promise<T>,\n shape: 'one' | 'many' | 'none' = 'none',\n keyExtra?: string,\n ): Promise<T> => {\n const physical = resolve(String(collection));\n const resolved = resolveQueryOptions(options);\n // What was sent to the DB, surfaced in the debugbar as the span's `params`:\n // the filter plus any driver options (sort/limit/projection/…) and, for\n // `distinct`, the field. `driverOpts` is session-free by construction\n // (session is stripped into `resolved.sdk`), so it is safe to capture.\n const sentParams: Record<string, unknown> = { filter };\n if (Object.keys(resolved.driverOpts).length > 0) sentParams.options = resolved.driverOpts;\n if (keyExtra !== undefined) sentParams.field = keyExtra;\n const noSession = !resolved.sdk.session;\n const useCache = opts.cache !== undefined && noSession && resolved.cache !== false;\n const shouldDedupe =\n resolved.dedupe !== false &&\n (resolved.dedupe === true || (opts.dedupeReads === true && noSession)) &&\n opts.inFlight !== undefined;\n\n // Schema-drift detection on DB fetch only: check the freshly-fetched docs\n // BEFORE they are cached, so `'throw'` mode never caches/exposes a drifted\n // document and `'report'` mode logs once per fetch (cache hits are skipped).\n // Projected reads ignore absent required fields but still validate values\n // that were actually returned.\n const checkDrift = (value: T): void => {\n const mode = resolveDriftMode(resolved.sdk.drift, opts.drift);\n if (mode === 'off') return;\n const partial = (resolved.driverOpts as { projection?: unknown }).projection !== undefined;\n const docs: Document[] =\n shape === 'many'\n ? (value as Document[])\n : shape === 'one' && value !== null\n ? [value as Document]\n : [];\n checkDocsDrift(\n {\n logger,\n db: dbLabel,\n drift: mode,\n ...(opts.getSchema !== undefined ? { getSchema: opts.getSchema } : {}),\n partial,\n },\n String(collection),\n opName,\n docs,\n );\n };\n\n const executeWrapped = () =>\n deps.trace(deps.meta(collection, opName, sentParams), () =>\n withRetry(() => execute(resolved), {\n maxAttempts: resolved.maxAttempts,\n delayMs: resolved.retryDelayMs,\n }),\n );\n\n // Hash ONCE and reuse for both the cache key and the dedup key.\n // The op name is part of the identity — `getOne`/`countDocuments`/`distinct`\n // on the same filter return different SHAPES, so they must never share a\n // cache entry (`distinct` also namespaces by its field). Pure retry/dedup\n // knobs are stripped so they can't fragment the cache; `drift` STAYS\n // because it changes read SEMANTICS (a 'throw' request must never be\n // served an entry that was cached under 'off'/'report' without\n // validation), and everything result-affecting (driver opts, session)\n // stays too. Computed LAZILY: session reads use neither cache nor dedup,\n // so their options (containing cyclic ClientSession objects) are never\n // serialized at all.\n const {\n maxAttempts: _ma,\n retryDelayMs: _rd,\n dedupe: _dd,\n cache: _ca,\n retryWrites: _rw,\n ...resultOptions\n } = (options ?? {}) as QueryOptions;\n void _ma;\n void _rd;\n void _dd;\n void _ca;\n void _rw;\n let payloadHash: string | undefined;\n const getPayloadHash = (): string => {\n if (payloadHash === undefined) {\n payloadHash = stableHash([opName, keyExtra ?? '', filter, resultOptions]);\n }\n return payloadHash;\n };\n\n const key = useCache\n ? opts.cache!.key(\n cacheCollectionKey(client.databaseName, physical, opts.cacheNamespace),\n getPayloadHash(),\n )\n : undefined;\n\n // Execution is created lazily so in-flight dedup can share ONE underlying\n // driver call (creating it eagerly would start a call per request).\n const fetchAndCheck = (): Promise<T> =>\n executeWrapped().then((value) => {\n checkDrift(value);\n return value;\n });\n\n const runOnce = (): Promise<T> => {\n if (useCache && key) {\n // Capture the collection version BEFORE fetching so a write that lands\n // mid-flight can never be hidden by a late cache set (see `get` guard).\n const colKey = cacheCollectionKey(client.databaseName, physical, opts.cacheNamespace);\n const versions = { [colKey]: opts.cache!.versionOf(colKey) };\n const hit = opts.cache!.get(key) as T | undefined;\n if (hit !== undefined) return Promise.resolve(hit);\n return fetchAndCheck().then((value) => {\n opts.cache!.set(key, value, undefined, undefined, versions);\n return value;\n });\n }\n return fetchAndCheck();\n };\n\n if (shouldDedupe) {\n // The collection VERSION is part of the dedup identity: a reader arriving\n // after a write invalidated the collection must start a FRESH load, never\n // join the pre-invalidation in-flight promise (mirrors HotCache's gen).\n const colKey = cacheCollectionKey(client.databaseName, physical, opts.cacheNamespace);\n const gen = opts.cache !== undefined ? opts.cache.versionOf(colKey) : '';\n // `await` (not a bare `return`): a non-awaited return from this async\n // function unwinds the caller chain in Bun's stack capture, so the ignex\n // debugbar's span origin would truncate here and never reach the route\n // handler that issued this read.\n return await opts.inFlight!.run(`${colKey}|${gen}|${getPayloadHash()}`, runOnce);\n }\n return await runOnce();\n };\n\n /** Translate `select` (field list) into a driver `projection`; strip `select`. */\n const normalizeFindOptions = <T>(\n options: FindQueryOptions<T> | undefined,\n ): FindOptions & QueryOptions => {\n if (!options) return {};\n const { select, ...rest } = options;\n if (!select || select.length === 0) return rest;\n const projection: Record<string, 1> = {};\n for (const field of select) projection[String(field)] = 1;\n return { ...rest, projection };\n };\n\n return {\n client,\n dbLabel,\n logger,\n opts,\n resolve,\n trace: deps.trace,\n meta: deps.meta,\n coll,\n toDriverFilter,\n run,\n writeRun,\n invalidate,\n stampCreate,\n stampUpdate,\n stampReplace,\n validateWrite,\n read,\n normalizeFindOptions,\n };\n};\n","import type { Document, Filter } from 'mongodb';\nimport type { FilterInput } from './filter-types.ts';\n\n/**\n * Soft-delete support. A soft-deleted row is one where `deletedAt` exists and is\n * non-null. Mirrors sdk-db's `crud-shared/soft-delete.ts`.\n */\nexport const buildMongoActiveFilter = (): Filter<Document> =>\n ({ $or: [{ deletedAt: { $exists: false } }, { deletedAt: null }] }) as Filter<Document>;\n\n/**\n * Merge a caller filter with the soft-delete \"active\" filter.\n * - softDelete=false → the caller filter unchanged\n * - empty/absent filter → active filter alone\n * - otherwise → `{ $and: [filter, active] }`\n */\nexport const mergeMongoActiveFilter = <T extends Document>(\n softDelete: boolean,\n filter?: FilterInput<T> | Filter<T>,\n): Filter<T> => {\n if (!softDelete) return (filter ?? {}) as Filter<T>;\n const active = buildMongoActiveFilter() as Filter<T>;\n if (!filter || Object.keys(filter).length === 0) return active;\n return { $and: [filter, active] } as Filter<T>;\n};\n","/**\n * Read op group: every CRUD query that goes through the shared cache + dedup +\n * drift pipeline (`getOne`, `findMany`, `findActive*`, `countDocuments`,\n * `distinct`, `estimatedDocumentCount`).\n *\n * A pure function of the shared `CrudContext` — composed into `makeCrudOps`\n * (see `./index.ts`). No mutable state beyond what the context closes over.\n */\nimport type {\n CountDocumentsOptions,\n DistinctOptions,\n Document,\n EstimatedDocumentCountOptions,\n FindCursor,\n FindOptions,\n} from 'mongodb';\nimport { DomainError } from '../../errors/index.ts';\nimport { hasHook, runHooks } from '../../hooks/hooks.ts';\nimport { DEFAULT_FIND_LIMIT } from '../../shared/constants.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport { mergeMongoActiveFilter } from '../../shared/soft-delete.ts';\nimport { cloneDeep } from '../../utils/clone.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type { ColNames, CrudContext, DocOf, FindQueryOptions } from './context.ts';\n\n/** Read ops produced for one database by `makeReadOps`. */\nexport type ReadOps<\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n> = ReturnType<typeof makeReadOps<TClients, TDb>>;\n\n/**\n * Build the read op set from the shared CRUD context. `getOne`/`findMany` are\n * returned (and internally referenced) so write ops can reuse them, e.g.\n * `updateWithVersion`'s cache-bypassing version read.\n */\nexport const makeReadOps = <\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n>(\n ctx: CrudContext<TClients, TDb>,\n) => {\n type C = ColNames<TClients, TDb>;\n type DocOf2<X extends C> = DocOf<TClients, TDb, X>;\n\n const { opts } = ctx;\n const { coll, toDriverFilter, read, normalizeFindOptions } = ctx;\n\n /** Fetch a single document by filter, or `null` when none matches. Cached + deduped. */\n const getOne = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): Promise<DocOf2<X> | null> => {\n const f = filter ?? {};\n const o = normalizeFindOptions(options);\n const doc = await read(\n collection,\n 'mongo.getOne',\n f,\n o,\n async (r) => {\n const opts: FindOptions = {\n ...(r.driverOpts as FindOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n };\n return (await coll(collection).findOne(\n toDriverFilter(f),\n opts,\n )) as unknown as DocOf2<X> | null;\n },\n 'one',\n );\n if (doc !== null && hasHook(opts.hooks, String(collection), 'afterRead')) {\n // Isolate hook mutation from the shared cache entry: hooks receive a\n // clone so mutating `ctx.doc` can't poison the cached document (which\n // stays pristine for every subsequent cache hit).\n const exposed = cloneDeep(doc) as DocOf2<X>;\n await runHooks(opts.hooks, String(collection), 'afterRead', {\n collection: String(collection),\n doc: exposed,\n });\n return exposed;\n }\n return doc;\n };\n\n /** Fetch a single document or throw `DomainError NOT_FOUND`. Accepts an optional custom error factory. */\n const getOneOrFail = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n errorFactory?: (name: string) => Error,\n ): Promise<DocOf2<X>> => {\n const doc = await getOne(collection, filter, options);\n if (doc === null) {\n if (errorFactory) throw errorFactory(String(collection));\n throw new DomainError(\n 'NOT_FOUND',\n `Document not found in collection \"${String(collection)}\"`,\n {\n collection: String(collection),\n },\n );\n }\n return doc;\n };\n\n /** Fetch many documents (default limit `DEFAULT_FIND_LIMIT`). Cached + deduped. */\n const findMany = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): Promise<DocOf2<X>[]> => {\n const merged = normalizeFindOptions({\n ...options,\n limit: options?.limit ?? DEFAULT_FIND_LIMIT,\n });\n const docs = await read(\n collection,\n 'mongo.findMany',\n filter ?? {},\n merged,\n async (r) => {\n const opts: FindOptions = {\n ...(r.driverOpts as FindOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n };\n return coll(collection)\n .find(toDriverFilter(filter ?? {}), opts)\n .toArray() as unknown as DocOf2<X>[];\n },\n 'many',\n );\n if (hasHook(opts.hooks, String(collection), 'afterRead')) {\n const exposed = cloneDeep(docs) as DocOf2<X>[];\n await runHooks(opts.hooks, String(collection), 'afterRead', {\n collection: String(collection),\n docs: exposed as Document[],\n });\n return exposed;\n }\n return docs;\n };\n\n /** Return a raw driver cursor (caller-owned — must be iterated/closed). No cache/dedup. */\n const findManyCursor = <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): FindCursor<DocOf2<X>> => {\n const {\n session,\n hint,\n maxTimeMS,\n batchSize,\n maxAttempts: _ma,\n retryDelayMs: _rd,\n dedupe: _d,\n cache: _c,\n ...rest\n } = normalizeFindOptions(options);\n const findOpts: FindOptions = {\n ...(rest as FindOptions),\n ...(session && { session }),\n ...(hint && { hint }),\n ...(maxTimeMS && { maxTimeMS }),\n ...(batchSize && { batchSize }),\n };\n return coll(collection).find(toDriverFilter(filter ?? {}), findOpts) as unknown as FindCursor<\n DocOf2<X>\n >;\n };\n\n /** Find many non-soft-deleted docs (merges the active filter automatically). */\n const findActive = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): Promise<DocOf2<X>[]> =>\n findMany(collection, mergeMongoActiveFilter(true, filter) as FilterInput<DocOf2<X>>, options);\n\n /** Find one non-soft-deleted doc (merges the active filter automatically). */\n const findActiveOne = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): Promise<DocOf2<X> | null> =>\n getOne(collection, mergeMongoActiveFilter(true, filter) as FilterInput<DocOf2<X>>, options);\n\n /** Count documents matching a filter. Cached + deduped. */\n const countDocuments = async <X extends C>(\n collection: X,\n filter?: FilterInput<DocOf2<X>>,\n options?: CountDocumentsOptions & QueryOptions,\n ): Promise<number> =>\n read(\n collection,\n 'mongo.countDocuments',\n filter ?? {},\n options,\n async (r) => {\n const opts: CountDocumentsOptions = {\n ...(r.driverOpts as CountDocumentsOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n };\n return await coll(collection).countDocuments(toDriverFilter(filter ?? {}), opts);\n },\n 'none',\n );\n\n /** Distinct values of `field` (schema-typed); routed through cache + dedup. */\n const distinct = async <X extends C, K extends keyof DocOf2<X>>(\n collection: X,\n field: K,\n filter?: FilterInput<DocOf2<X>>,\n options?: FindQueryOptions<DocOf2<X>>,\n ): Promise<Array<DocOf2<X>[K]>> => {\n const f = filter ?? {};\n const o = normalizeFindOptions(options);\n return read(\n collection,\n 'mongo.distinct',\n f,\n o,\n async (r) => {\n const opts: FindOptions = {\n ...(r.driverOpts as FindOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n };\n return coll(collection).distinct(\n String(field),\n toDriverFilter(f),\n opts as DistinctOptions,\n ) as unknown as Array<DocOf2<X>[K]>;\n },\n 'none',\n String(field),\n );\n };\n\n /** Approximate collection count from metadata (fast, not filter-aware). Cached + deduped. */\n const estimatedDocumentCount = async <X extends C>(\n collection: X,\n options?: EstimatedDocumentCountOptions & QueryOptions,\n ): Promise<number> =>\n read(\n collection,\n 'mongo.estimatedDocumentCount',\n {},\n options,\n async (r) => {\n const opts: EstimatedDocumentCountOptions = {\n ...(r.driverOpts as EstimatedDocumentCountOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n };\n return await coll(collection).estimatedDocumentCount(opts);\n },\n 'none',\n );\n\n return {\n getOne,\n getOneOrFail,\n findMany,\n findManyCursor,\n findActive,\n findActiveOne,\n countDocuments,\n distinct,\n estimatedDocumentCount,\n };\n};\n","/**\n * Watch/query-builder op group: `watchCollection` (caller-owned change stream)\n * and `query` (the fluent `QueryBuilder` entry point, whose reads flow through\n * the shared cache + dedup pipeline).\n *\n * Composed into `makeCrudOps` (see `./index.ts`).\n */\nimport type { ChangeStream, ChangeStreamOptions, Document, FindOptions } from 'mongodb';\nimport { QueryBuilder } from '../../query-builder/query-builder.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type { ColNames, CrudContext, DocOf } from './context.ts';\n\n/** Watch/query ops produced for one database by `makeWatchOps`. */\nexport type WatchOps<\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n> = ReturnType<typeof makeWatchOps<TClients, TDb>>;\n\n/** Build the watch + query-builder op set from the shared CRUD context. */\nexport const makeWatchOps = <\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n>(\n ctx: CrudContext<TClients, TDb>,\n) => {\n type C = ColNames<TClients, TDb>;\n type DocOf2<X extends C> = DocOf<TClients, TDb, X>;\n\n const { client, resolve, coll, read } = ctx;\n\n /**\n * Open a change stream on a collection. The returned `ChangeStream` is owned\n * by the caller — attach an `'error'` listener and call `.close()` when done\n * so a fire-and-forget stream never becomes an unhandled rejection.\n */\n const watchCollection = <X extends C>(\n collection: X,\n pipeline?: Document[],\n options?: ChangeStreamOptions,\n ): ChangeStream<DocOf2<X>> => coll(collection).watch(pipeline, options);\n\n /** Fluent query builder entry point. Reads flow through the cache + dedup pipeline. */\n const query = <X extends C>(collection: X): QueryBuilder<DocOf2<X>> => {\n const physical = resolve(String(collection));\n const handle = client.collection<DocOf2<X>>(physical);\n return new QueryBuilder<DocOf2<X>>({\n physicalName: physical,\n collection: handle,\n run: async <T>(\n opName: string,\n filter: FilterInput<DocOf2<X>>,\n execute: (driverOpts: FindOptions) => Promise<T>,\n options?: QueryOptions,\n ): Promise<T> =>\n read(\n collection,\n opName,\n filter,\n options,\n async (r) => {\n const opts: FindOptions = {\n ...(r.driverOpts as FindOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n };\n return await execute(opts);\n },\n opName === 'mongo.getOne' ? 'one' : opName === 'mongo.findMany' ? 'many' : 'none',\n ),\n });\n };\n\n return {\n watchCollection,\n query,\n };\n};\n","/**\n * Write op group: every mutating CRUD operation. All writes invalidate the\n * collection's cache and fire lifecycle hooks (`beforeUpdate`/`afterUpdate`\n * on update-shaped ops including `updateMany`/`findOneAndUpdate`/`upsert`,\n * `beforeDelete`/`afterDelete` on delete-shaped ops including `deleteMany`\n * and `softDeleteOne`). The two RAW escape hatches (`bulkWrite`, and the\n * per-operation nature of `bulkUpsert`) are hook-translucent by design —\n * there is no single filter/doc to hand a hook. Transient driver errors are\n * retried only when the caller opts in via `QueryOptions.retryWrites`\n * (at-least-once semantics).\n *\n * Composed into `makeCrudOps` (see `./index.ts`). Takes the read ops object as\n * an explicit dependency so `updateWithVersion` can reuse `getOne` for its\n * cache-bypassing version read — dependency injection rather than a shared\n * closure.\n */\nimport type {\n AnyBulkWriteOperation,\n BulkWriteOptions,\n DeleteOptions,\n DeleteResult,\n Document,\n Filter,\n FindOneAndDeleteOptions,\n FindOneAndReplaceOptions,\n FindOneAndUpdateOptions,\n FindOptions,\n InsertManyResult,\n InsertOneOptions,\n InsertOneResult,\n OptionalUnlessRequiredId,\n ReplaceOptions,\n UpdateFilter,\n UpdateOptions,\n UpdateResult,\n} from 'mongodb';\nimport { BadRequest } from '../../errors/index.ts';\nimport { type HookContext, runHooks } from '../../hooks/hooks.ts';\nimport { MAX_BATCH_OPS } from '../../shared/constants.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport { mergeMongoActiveFilter } from '../../shared/soft-delete.ts';\nimport type { QueryOptions } from '../query-options.ts';\nimport type { UpdateInput } from '../update-types.ts';\nimport type {\n ColNames,\n CrudContext,\n DocOf,\n InsertInput,\n VersionedUpdateResult,\n} from './context.ts';\nimport type { ReadOps } from './read-ops.ts';\n\n/** Write ops produced for one database by `makeWriteOps`. */\nexport type WriteOps<\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n> = ReturnType<typeof makeWriteOps<TClients, TDb>>;\n\n/**\n * Build the write op set from the shared CRUD context. `readOps.getOne` is\n * injected so versioned updates read committed state without the cache.\n */\nexport const makeWriteOps = <\n TClients extends import('../../types.ts').DbClientsDefinition,\n TDb extends import('../../types.ts').ExtractDbNames<TClients>,\n>(\n ctx: CrudContext<TClients, TDb>,\n readOps: ReadOps<TClients, TDb>,\n) => {\n type C = ColNames<TClients, TDb>;\n type DocOf2<X extends C> = DocOf<TClients, TDb, X>;\n\n const { opts } = ctx;\n const {\n coll,\n toDriverFilter,\n writeRun,\n invalidate,\n stampCreate,\n stampUpdate,\n stampReplace,\n validateWrite,\n } = ctx;\n const { getOne } = readOps;\n\n /**\n * Post-commit hook runner. `after*` hooks fire AFTER the DB write and cache\n * invalidation have succeeded — a throwing hook must NOT fail the operation:\n * the caller would see \"failed\" for already-committed state, and a retrying\n * caller would duplicate the write. Log loudly and keep the committed result.\n */\n const safeAfterHooks = async (\n collection: string,\n name: 'afterCreate' | 'afterUpdate' | 'afterDelete',\n hookCtx: HookContext<Document>,\n ): Promise<void> => {\n try {\n await runHooks(opts.hooks, collection, name, hookCtx);\n } catch (err) {\n ctx.logger.error?.(\n {\n collection,\n hook: name,\n error: err instanceof Error ? err.message : String(err),\n },\n `post-commit ${name} hook failed; DB write is already committed`,\n );\n }\n };\n\n /** Insert one document (runs before/after-create hooks; stamps timestamps; invalidates cache). */\n const insertOne = async <X extends C>(\n collection: X,\n doc: InsertInput<DocOf2<X>>,\n options?: InsertOneOptions & QueryOptions,\n ): Promise<InsertOneResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeCreate', {\n collection: String(collection),\n doc: doc as Document,\n });\n stampCreate(collection, doc as Document);\n validateWrite(collection, doc as Document);\n const result = await writeRun(\n collection,\n 'mongo.insertOne',\n async (r) => {\n const insertOpts: InsertOneOptions = {\n ...(r.driverOpts as InsertOneOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return await coll(collection).insertOne(\n doc as OptionalUnlessRequiredId<DocOf2<X>>,\n insertOpts,\n );\n },\n options,\n { doc },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterCreate', {\n collection: String(collection),\n doc: doc as Document,\n });\n return result as InsertOneResult<DocOf2<X>>;\n };\n\n /** Insert many documents in one call (guards against batches over `MAX_BATCH_OPS`). */\n const insertMany = async <X extends C>(\n collection: X,\n docs: ReadonlyArray<InsertInput<DocOf2<X>>>,\n options?: BulkWriteOptions & QueryOptions,\n ): Promise<InsertManyResult<DocOf2<X>>> => {\n // Guard BEFORE stamping/hooking — don't pay O(n) work for an inevitable throw.\n if (docs.length > MAX_BATCH_OPS) {\n throw new BadRequest(\n `insertMany: too many docs (${docs.length} > ${MAX_BATCH_OPS}); split the batch`,\n );\n }\n await runHooks(opts.hooks, String(collection), 'beforeCreate', {\n collection: String(collection),\n docs: docs as unknown as Document[],\n });\n for (const d of docs) {\n stampCreate(collection, d as Document);\n validateWrite(collection, d as Document);\n }\n const result = await writeRun(\n collection,\n 'mongo.insertMany',\n async (r) => {\n const bulkOpts: BulkWriteOptions = {\n ...(r.driverOpts as BulkWriteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return coll(collection).insertMany(\n docs as ReadonlyArray<OptionalUnlessRequiredId<DocOf2<X>>>,\n bulkOpts,\n );\n },\n options,\n { docs },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterCreate', {\n collection: String(collection),\n docs: docs as unknown as Document[],\n });\n return result as InsertManyResult<DocOf2<X>>;\n };\n\n /** Update the first document matching a filter (runs before/after-update hooks). */\n const updateOne = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n update: UpdateInput<DocOf2<X>>,\n options?: UpdateOptions & QueryOptions,\n ): Promise<UpdateResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const effective = stampUpdate(collection, update);\n const result = await writeRun(\n collection,\n 'mongo.updateOne',\n async (r) => {\n const updateOpts: UpdateOptions = {\n ...(r.driverOpts as UpdateOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return coll(collection).updateOne(\n toDriverFilter(filter),\n effective as unknown as UpdateFilter<DocOf2<X>>,\n updateOpts,\n );\n },\n options,\n { filter, update: effective },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Update every document matching a filter (runs before/after-update hooks). */\n const updateMany = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n update: UpdateInput<DocOf2<X>>,\n options?: UpdateOptions & QueryOptions,\n ): Promise<UpdateResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const effective = stampUpdate(collection, update);\n const result = await writeRun(\n collection,\n 'mongo.updateMany',\n async (r) => {\n const updateOpts: UpdateOptions = {\n ...(r.driverOpts as UpdateOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return coll(collection).updateMany(\n toDriverFilter(filter),\n effective as unknown as UpdateFilter<DocOf2<X>>,\n updateOpts,\n );\n },\n options,\n { filter, update: effective },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Find one + update atomically (runs before/after-update hooks). */\n const findOneAndUpdate = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n update: UpdateInput<DocOf2<X>>,\n options?: FindOneAndUpdateOptions & QueryOptions,\n ): Promise<DocOf2<X> | null> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const effective = stampUpdate(collection, update);\n const result = await writeRun(\n collection,\n 'mongo.findOneAndUpdate',\n async (r) => {\n const fOpts = {\n ...(r.driverOpts as FindOneAndUpdateOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined\n ? { hint: r.sdk.hint as FindOneAndUpdateOptions['hint'] }\n : {}),\n // `after` is the ORM's default, but honor an explicit caller override.\n returnDocument: (r.driverOpts as FindOneAndUpdateOptions).returnDocument ?? 'after',\n } as FindOneAndUpdateOptions;\n return coll(collection).findOneAndUpdate(\n toDriverFilter(filter),\n effective as unknown as UpdateFilter<DocOf2<X>>,\n fOpts,\n ) as unknown as DocOf2<X> | null;\n },\n options,\n { filter, update: effective },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Find one + replace atomically with a full replacement doc (runs update hooks). */\n const findOneAndReplace = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n replacement: DocOf2<X>,\n options?: FindOneAndReplaceOptions & QueryOptions,\n ): Promise<DocOf2<X> | null> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const effective = stampReplace(collection, replacement as Document) as DocOf2<X>;\n validateWrite(collection, effective as Document, false);\n const result = await writeRun(\n collection,\n 'mongo.findOneAndReplace',\n async (r) => {\n const fOpts = {\n ...(r.driverOpts as FindOneAndReplaceOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined\n ? { hint: r.sdk.hint as FindOneAndReplaceOptions['hint'] }\n : {}),\n // `after` is the ORM's default, but honor an explicit caller override.\n returnDocument: (r.driverOpts as FindOneAndReplaceOptions).returnDocument ?? 'after',\n } as FindOneAndReplaceOptions;\n return coll(collection).findOneAndReplace(\n toDriverFilter(filter),\n effective,\n fOpts,\n ) as unknown as DocOf2<X> | null;\n },\n options,\n { filter, replacement: effective },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Replace one document by filter (full replacement; runs before/after-update hooks). */\n const replaceOne = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n replacement: InsertInput<DocOf2<X>>,\n options?: ReplaceOptions & QueryOptions,\n ): Promise<UpdateResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const effective = stampReplace(collection, replacement as Document);\n validateWrite(collection, effective, false);\n const result = await writeRun(\n collection,\n 'mongo.replaceOne',\n async (r) => {\n const repOpts: ReplaceOptions = {\n ...(r.driverOpts as ReplaceOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return coll(collection).replaceOne(\n toDriverFilter(filter),\n effective as unknown as OptionalUnlessRequiredId<DocOf2<X>>,\n repOpts,\n );\n },\n options,\n { filter, replacement },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Delete the first document matching a filter (runs before/after-delete hooks). */\n const deleteOne = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n options?: DeleteOptions & QueryOptions,\n ): Promise<DeleteResult> => {\n await runHooks(opts.hooks, String(collection), 'beforeDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const result = await writeRun(\n collection,\n 'mongo.deleteOne',\n async (r) => {\n const delOpts: DeleteOptions = {\n ...(r.driverOpts as DeleteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return await coll(collection).deleteOne(toDriverFilter(filter), delOpts);\n },\n options,\n { filter },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Delete every document matching a filter (runs before/after-delete hooks). */\n const deleteMany = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n options?: DeleteOptions & QueryOptions,\n ): Promise<DeleteResult> => {\n await runHooks(opts.hooks, String(collection), 'beforeDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const result = await writeRun(\n collection,\n 'mongo.deleteMany',\n async (r) => {\n const delOpts: DeleteOptions = {\n ...(r.driverOpts as DeleteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return await coll(collection).deleteMany(toDriverFilter(filter), delOpts);\n },\n options,\n { filter },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Find one + delete atomically (runs before/after-delete hooks). */\n const findOneAndDelete = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n options?: FindOneAndDeleteOptions & QueryOptions,\n ): Promise<DocOf2<X> | null> => {\n await runHooks(opts.hooks, String(collection), 'beforeDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const result = await writeRun(\n collection,\n 'mongo.findOneAndDelete',\n async (r) => {\n const fOpts = {\n ...(r.driverOpts as FindOneAndDeleteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined\n ? { hint: r.sdk.hint as FindOneAndDeleteOptions['hint'] }\n : {}),\n } as FindOneAndDeleteOptions;\n return coll(collection).findOneAndDelete(\n toDriverFilter(filter),\n fOpts,\n ) as unknown as DocOf2<X> | null;\n },\n options,\n { filter },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /**\n * Soft-delete one doc: sets `deletedAt` instead of removing it (active reads\n * exclude it). Stamps `updatedAt` per the collection's timestamps config and\n * runs before/after-delete hooks — a soft delete IS a delete from the\n * lifecycle's point of view.\n */\n const softDeleteOne = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n options?: UpdateOptions & QueryOptions,\n ): Promise<UpdateResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const active = mergeMongoActiveFilter(true, filter);\n const effective = stampUpdate(collection, {\n $set: { deletedAt: new Date() },\n } as unknown as UpdateInput<DocOf2<X>>);\n const result = await writeRun(\n collection,\n 'mongo.softDeleteOne',\n async (r) => {\n const updateOpts: UpdateOptions = {\n ...(r.driverOpts as UpdateOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return coll(collection).updateOne(\n active,\n effective as unknown as UpdateFilter<DocOf2<X>>,\n updateOpts,\n );\n },\n options,\n { filter, update: effective },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterDelete', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Upsert one document (insert when the filter matches nothing; runs update hooks). */\n const upsert = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n update: UpdateInput<DocOf2<X>>,\n options?: UpdateOptions & QueryOptions,\n ): Promise<UpdateResult<DocOf2<X>>> => {\n await runHooks(opts.hooks, String(collection), 'beforeUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n const formatted = stampUpdate(collection, update) as unknown as UpdateFilter<DocOf2<X>>;\n const result = await writeRun(\n collection,\n 'mongo.upsert',\n async (r) => {\n const updateOpts: UpdateOptions = {\n ...(r.driverOpts as UpdateOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n upsert: true,\n };\n return await coll(collection).updateOne(toDriverFilter(filter), formatted, updateOpts);\n },\n options,\n { filter, update: formatted },\n );\n invalidate(collection);\n await safeAfterHooks(String(collection), 'afterUpdate', {\n collection: String(collection),\n filter: filter as Filter<Document>,\n });\n return result;\n };\n\n /** Bulk upsert: many `updateOne`-style upserts in one write (guarded by `MAX_BATCH_OPS`). */\n const bulkUpsert = async <X extends C>(\n collection: X,\n operations: Array<{\n filter: FilterInput<DocOf2<X>>;\n update: UpdateInput<DocOf2<X>>;\n upsert?: boolean;\n }>,\n options?: BulkWriteOptions & QueryOptions,\n ): Promise<Document> => {\n // Guard BEFORE mapping/stamping — don't pay O(n) work for an inevitable throw.\n if (operations.length > MAX_BATCH_OPS) {\n throw new BadRequest(\n `bulkUpsert: too many operations (${operations.length} > ${MAX_BATCH_OPS}); split the batch`,\n );\n }\n const writes = operations.map((op) => ({\n updateOne: {\n filter: op.filter,\n update: stampUpdate(collection, op.update) as unknown as UpdateFilter<DocOf2<X>>,\n upsert: op.upsert ?? true,\n },\n })) as unknown as AnyBulkWriteOperation<DocOf2<X>>[];\n const result = await writeRun(\n collection,\n 'mongo.bulkUpsert',\n async (r) => {\n const bulkOpts: BulkWriteOptions = {\n ...(r.driverOpts as BulkWriteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return await coll(collection).bulkWrite(writes, bulkOpts);\n },\n options,\n { operations },\n );\n invalidate(collection);\n return result;\n };\n\n /** Generic `bulkWrite` with arbitrary driver bulk operations (guarded by `MAX_BATCH_OPS`). */\n const bulkWrite = async <X extends C>(\n collection: X,\n operations: AnyBulkWriteOperation<DocOf2<X>>[],\n options?: BulkWriteOptions & QueryOptions,\n ): Promise<Document> => {\n if (operations.length > MAX_BATCH_OPS) {\n throw new BadRequest(\n `bulkWrite: too many operations (${operations.length} > ${MAX_BATCH_OPS}); split the batch`,\n );\n }\n const result = await writeRun(\n collection,\n 'mongo.bulkWrite',\n async (r) => {\n const bulkOpts: BulkWriteOptions = {\n ...(r.driverOpts as BulkWriteOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n };\n return await coll(collection).bulkWrite(operations, bulkOpts);\n },\n options,\n { operations },\n );\n invalidate(collection);\n return result;\n };\n\n /** Optimistic lock on a `__v` field: read → CAS update → version_conflict on miss. */\n const updateWithVersion = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n update: UpdateInput<DocOf2<X>>,\n options?: FindOneAndUpdateOptions & QueryOptions,\n ): Promise<VersionedUpdateResult<DocOf2<X>>> => {\n // The version read must reflect committed state — bypass the read cache\n // (a stale or cached-`null` entry would yield spurious not_found /\n // version_conflict even when the doc is present/current in the DB).\n const existing = await getOne(collection, filter, {\n ...(options as FindOptions & QueryOptions),\n cache: false,\n });\n if (!existing) return { ok: false, reason: 'not_found' };\n\n // A doc that has never been versioned has NO `__v` field — `{__v: 0}` would\n // never match, so match on the field's absence for the first write.\n const current = (existing as Document & { __v?: number }).__v;\n const versionFilter: Document =\n current === undefined ? { __v: { $exists: false } } : { __v: current };\n\n const formatted = stampUpdate(collection, update) as Document;\n const versionedUpdate = {\n ...formatted,\n $inc: { ...((formatted as Document).$inc as Document | undefined), __v: 1 },\n } as unknown as UpdateInput<DocOf2<X>>;\n\n const result = await findOneAndUpdate(\n collection,\n { ...filter, ...versionFilter } as unknown as FilterInput<DocOf2<X>>,\n versionedUpdate,\n { ...options, returnDocument: 'after' },\n );\n if (result === null) return { ok: false, reason: 'version_conflict' };\n return { ok: true, doc: result };\n };\n\n return {\n insertOne,\n insertMany,\n updateOne,\n updateMany,\n findOneAndUpdate,\n findOneAndReplace,\n deleteOne,\n deleteMany,\n softDeleteOne,\n upsert,\n bulkUpsert,\n bulkWrite,\n updateWithVersion,\n findOneAndDelete,\n replaceOne,\n };\n};\n","/**\n * CRUD op factory — `makeCrudOps` — and the public CRUD types.\n *\n * `makeCrudOps` is the composition root of the CRUD layer: it builds ONE shared\n * context (`createCrudContext` in `./context.ts`) and spreads the three op\n * groups it produces:\n *\n * - `makeReadOps` → every read op (cache/dedup/drift pipeline)\n * - `makeWriteOps` → every write op (hooks + timestamps + cache invalidation)\n * - `makeWatchOps` → change streams + fluent query builder\n *\n * The public surface (method names, signatures, exported types) is identical to\n * the historical single-file `crud.ts` — this is a pure organizational split.\n */\nimport type { Db } from 'mongodb';\nimport type { DbClientsDefinition, ExtractDbNames } from '../../types.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { type CrudOpsOptions, createCrudContext } from './context.ts';\nimport { makeReadOps } from './read-ops.ts';\nimport { makeWatchOps } from './watch-ops.ts';\nimport { makeWriteOps } from './write-ops.ts';\n\n/**\n * Build the CRUD operation set for one database. Every method is collection-name\n * first and schema-typed (no `<TDoc>` at call sites). Reads go through the\n * cache + in-flight dedup path; writes invalidate the cache for that collection\n * and fire lifecycle hooks.\n */\nexport const makeCrudOps = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n client: Db,\n dbLabel: string,\n logger: LoggerLike,\n opts: CrudOpsOptions,\n) => {\n const ctx = createCrudContext<TClients, TDb>(client, dbLabel, logger, opts);\n const readOps = makeReadOps<TClients, TDb>(ctx);\n return {\n ...readOps,\n ...makeWriteOps<TClients, TDb>(ctx, readOps),\n ...makeWatchOps<TClients, TDb>(ctx),\n };\n};\n\nexport type CrudOps<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> = ReturnType<typeof makeCrudOps<TClients, TDb>>;\n\n// Re-export the public CRUD types so `makeCrudOps` consumers get the full\n// surface from the folder barrel, matching the old single-module exports.\nexport type {\n CrudContext,\n CrudOpsOptions,\n FindQueryOptions,\n InsertInput,\n TimestampsByCollection,\n VersionedUpdateResult,\n} from './context.ts';\nexport type { ReadOps } from './read-ops.ts';\nexport type { WatchOps } from './watch-ops.ts';\nexport type { WriteOps } from './write-ops.ts';\n","/**\n * Keyset (cursor) pagination helpers — pure, DB-agnostic.\n *\n * Unlike offset pagination, keyset pagination filters on the *last seen* row's\n * sort values, so it stays O(log n) regardless of page depth (no deep `$skip`)\n * and is stable under concurrent inserts. It cannot report a total count —\n * use `paginateFlexible` ($facet) when you need totals.\n *\n * Requirement: every sort key (and the `_id` tiebreaker) should exist on every\n * document for deterministic ordering, since the boundary comparison relies on\n * them.\n */\n\nimport type { Document } from 'mongodb';\nimport { BSON, ObjectId } from 'mongodb';\n\nconst { EJSON } = BSON;\n\nimport { BadRequest } from '../errors/index.ts';\n\n/** Serializable, tagged representation of a cursor boundary value. */\ntype TaggedValue = {\n t: 'oid' | 'date' | 'string' | 'number' | 'boolean' | 'null' | 'bson';\n v?: string | number | boolean;\n};\n\nexport interface KeysetCursor {\n /** The sort spec this cursor belongs to (used to reject mismatched cursors). */\n sort: Record<string, 1 | -1>;\n /** Boundary field values, in sort-key order. */\n values: unknown[];\n}\n\nconst tag = (value: unknown): TaggedValue => {\n if (value instanceof ObjectId) return { t: 'oid', v: value.toHexString() };\n if (value instanceof Date) return { t: 'date', v: value.toISOString() };\n if (typeof value === 'string') return { t: 'string', v: value };\n if (typeof value === 'number') return { t: 'number', v: value };\n if (typeof value === 'boolean') return { t: 'boolean', v: value };\n if (value === null || value === undefined) return { t: 'null' };\n if (typeof value === 'object' && '_bsontype' in value) {\n return { t: 'bson', v: EJSON.stringify(value, { relaxed: false }) };\n }\n // A drifted sort-field value (object/array/…) cannot be encoded losslessly\n // into a cursor — a `String(value)` fallback would silently corrupt\n // pagination (the decoded boundary could never compare against the real\n // field type). Fail loudly instead of serving a wrong page.\n throw new BadRequest(\n `paginateCursor: unsupported sort value type \"${typeof value}\" — key values must be ObjectId, Date, string, number, boolean, or null`,\n );\n};\n\nconst untag = (tagged: TaggedValue): unknown => {\n switch (tagged.t) {\n case 'oid':\n if (typeof tagged.v !== 'string') {\n throw new BadRequest('paginateCursor: invalid cursor — oid value must be a string');\n }\n return new ObjectId(tagged.v);\n case 'date':\n if (typeof tagged.v !== 'string') {\n throw new BadRequest('paginateCursor: invalid cursor — date value must be a string');\n }\n return new Date(tagged.v);\n case 'string':\n if (typeof tagged.v !== 'string') {\n throw new BadRequest('paginateCursor: invalid cursor — string value expected');\n }\n return tagged.v;\n case 'number':\n if (typeof tagged.v !== 'number') {\n throw new BadRequest('paginateCursor: invalid cursor — number value expected');\n }\n return tagged.v;\n case 'boolean':\n if (typeof tagged.v !== 'boolean') {\n throw new BadRequest('paginateCursor: invalid cursor — boolean value expected');\n }\n return tagged.v;\n case 'null':\n return null;\n case 'bson':\n if (typeof tagged.v !== 'string') {\n throw new BadRequest('paginateCursor: invalid cursor — BSON value must be a string');\n }\n return EJSON.parse(tagged.v, { relaxed: false });\n }\n};\n\n/** Base64url-encode a cursor. The payload is opaque to callers. */\nexport const encodeCursor = (cursor: KeysetCursor): string =>\n Buffer.from(\n JSON.stringify({\n sort: cursor.sort,\n values: cursor.values.map(tag),\n }),\n 'utf8',\n ).toString('base64url');\n\n/** Decode + validate an opaque cursor. Throws on malformed input. */\nexport const decodeCursor = (cursor: string): KeysetCursor => {\n let parsed: { sort?: Record<string, 1 | -1>; values?: TaggedValue[] };\n try {\n parsed = JSON.parse(Buffer.from(cursor, 'base64url').toString('utf8'));\n } catch {\n throw new BadRequest('paginateCursor: invalid cursor');\n }\n if (!parsed || typeof parsed !== 'object' || !parsed.sort || !Array.isArray(parsed.values)) {\n throw new BadRequest('paginateCursor: invalid cursor payload');\n }\n return { sort: parsed.sort, values: parsed.values.map(untag) };\n};\n\n/**\n * Build the keyset filter for the next page.\n *\n * Sort keys `[k1(d1), k2(d2), ...]` with boundary values `[v1, v2, ...]` produce\n * the standard disjunction of prefix-equalities plus a strict comparison on the\n * next key:\n *\n * k1 ≻ v1 OR (k1 = v1 AND k2 ≻ v2) OR ... OR (k1 = v1 AND ... AND kn ≻ vn)\n *\n * where `≻` is `>` for ascending keys and `<` for descending keys when\n * `direction` is `'after'` (inverted for `'before'`). `_id` is the natural\n * unique tiebreaker.\n */\nexport const buildKeysetFilter = (\n sort: Record<string, 1 | -1>,\n values: unknown[],\n direction: 'after' | 'before',\n): Document => {\n const keys = Object.entries(sort);\n const ors: Document[] = [];\n for (let i = 0; i < keys.length; i++) {\n const cond: Document = {};\n for (let j = 0; j < i; j++) {\n const [f] = keys[j]!;\n cond[f] = values[j];\n }\n const [field, dir] = keys[i]!;\n const value = values[i];\n const cmp = direction === 'after' ? (dir === 1 ? '$gt' : '$lt') : dir === 1 ? '$lt' : '$gt';\n cond[field] = { [cmp]: value };\n ors.push(cond);\n }\n return { $or: ors };\n};\n","/**\n * Keyset (cursor) pagination strategy — `paginateCursor`: O(log n) per page,\n * stable under concurrent writes, no total count. `after` walks forward from a\n * `nextCursor`; `before` walks backward by reversing the effective sort. Sort\n * must include a unique tiebreaker (`_id`).\n */\nimport type { Document, FindOptions } from 'mongodb';\nimport { BadRequest } from '../../errors/index.ts';\nimport { DEFAULT_FIND_LIMIT, DEFAULT_MAX_LIMIT } from '../../shared/constants.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport { buildKeysetFilter, decodeCursor, encodeCursor } from '../../shared/keyset.ts';\nimport { normalizePageLimit } from '../../shared/pagination-math.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport { defineCrudOp } from '../crud-op.ts';\nimport { checkDocsDrift } from '../drift.ts';\nimport { resolveDriftMode } from '../query-options.ts';\nimport type {\n CursorPage,\n CursorPaginationConfig,\n PaginationCtx,\n PaginationDocOf,\n} from './types.ts';\n\n/** Build the `paginateCursor` closure from the shared pagination context. */\nexport const makePaginateCursor = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: PaginationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = PaginationDocOf<TClients, TDb, X>;\n\n const { client, dbLabel, logger, opts, resolve, deps } = ctx;\n\n /**\n * Keyset (cursor) pagination — O(log n) per page, stable under concurrent\n * writes, no total count. `after` walks forward from a `nextCursor`;\n * `before` walks backward. Sort must include a unique tiebreaker (`_id`).\n */\n const paginateCursor = async <X extends C>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n config: CursorPaginationConfig,\n ): Promise<CursorPage<DocOf2<X>>> => {\n const sortKeys = Object.entries(config.sort);\n const uniqueTiebreaker = config.uniqueTiebreaker ?? '_id';\n if (sortKeys.length === 0) {\n throw new BadRequest(\n 'paginateCursor: `sort` is required (include a unique tiebreaker like `_id`)',\n );\n }\n if (sortKeys.at(-1)?.[0] !== uniqueTiebreaker) {\n throw new BadRequest(\n `paginateCursor: the final sort key must be the unique tiebreaker \"${uniqueTiebreaker}\"`,\n );\n }\n if (config.before !== undefined && config.after !== undefined) {\n throw new BadRequest('paginateCursor: provide either `after` or `before`, not both');\n }\n const limit = normalizePageLimit(\n { page: 1, ...(config.limit !== undefined ? { limit: config.limit } : {}) },\n config.maxLimit ?? DEFAULT_MAX_LIMIT,\n { limit: DEFAULT_FIND_LIMIT },\n ).limit;\n\n const backwards = config.before !== undefined && config.after === undefined;\n // In reversed space \"after the cursor\" == \"before the cursor\" in forward space.\n const effectiveSort: Record<string, 1 | -1> = backwards\n ? Object.fromEntries(sortKeys.map(([f, d]) => [f, (d * -1) as 1 | -1]))\n : config.sort;\n\n let filter: Document = baseFilter as Document;\n if (config.after !== undefined || config.before !== undefined) {\n const cursor = (config.after ?? config.before) as string;\n const decoded = decodeCursor(cursor);\n // Sort keys are ORDER-SENSITIVE: key precedence (primary/secondary/…)\n // defines the ordering, so a cursor built with a different key order is a\n // *different* sort and must be rejected — values are positional per key.\n if (JSON.stringify(decoded.sort) !== JSON.stringify(config.sort)) {\n throw new BadRequest('paginateCursor: cursor was created with a different sort');\n }\n if (decoded.values.length !== sortKeys.length) {\n throw new BadRequest('paginateCursor: cursor was created with a different sort');\n }\n filter = {\n $and: [baseFilter as Document, buildKeysetFilter(effectiveSort, decoded.values, 'after')],\n };\n }\n\n const rows = await defineCrudOp(\n deps,\n collection,\n 'mongo.paginateCursor',\n async (r) => {\n const findOpts: FindOptions = {\n ...(r.driverOpts as FindOptions),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n ...(r.sdk.batchSize !== undefined ? { batchSize: r.sdk.batchSize } : {}),\n };\n return client\n .collection<Document>(resolve(String(collection)))\n .find(filter, findOpts)\n .sort(effectiveSort as Document)\n .limit(limit + 1)\n .toArray();\n },\n config.queryOptions,\n false,\n { filter, sort: effectiveSort, limit },\n );\n\n const hasMore = rows.length > limit;\n const page = backwards ? rows.slice(0, limit).reverse() : rows.slice(0, limit);\n checkDocsDrift(\n {\n logger,\n db: dbLabel,\n drift: resolveDriftMode(config.queryOptions?.drift, opts.drift),\n ...(opts.getSchema !== undefined ? { getSchema: opts.getSchema } : {}),\n },\n String(collection),\n 'mongo.paginateCursor',\n page as unknown as Document[],\n );\n const boundary = backwards ? page[0] : page[page.length - 1];\n let nextCursor: string | null = null;\n if (hasMore && boundary !== undefined) {\n const values = sortKeys.map(([f]) =>\n f\n .split('.')\n .reduce<unknown>(\n (value, part) =>\n value !== null && typeof value === 'object'\n ? (value as Record<string, unknown>)[part]\n : undefined,\n boundary,\n ),\n );\n if (values.some((v) => v === undefined)) {\n // A boundary doc missing a sort field would encode as `null`, whose\n // keyset comparison ALSO matches missing fields — pages could loop or\n // skip. Fail loudly instead of corrupting pagination.\n throw new BadRequest(\n 'paginateCursor: boundary document is missing a sort field — every sort key must exist on every document for keyset pagination',\n );\n }\n nextCursor = encodeCursor({ sort: config.sort, values });\n }\n return { data: page as unknown as DocOf2<X>[], nextCursor, hasMore };\n };\n\n return { paginateCursor };\n};\n","/**\n * Offset pagination strategy — `paginateFlexible`, via a **single `$facet`\n * aggregation round-trip**: `$match` + `$facet { data: [sort/skip/limit/post],\n * totalCount: [$count] }`. One network call returns both the page and the total\n * — the ORM's key pagination perf win vs the classic count-then-find pattern.\n */\nimport type { Abortable, AggregateOptions, Document } from 'mongodb';\nimport { BadRequest } from '../../errors/index.ts';\nimport { DEFAULT_FIND_LIMIT, DEFAULT_MAX_LIMIT } from '../../shared/constants.ts';\nimport type { FilterInput } from '../../shared/filter-types.ts';\nimport { normalizePageLimit } from '../../shared/pagination-math.ts';\nimport { buildPaginationResult, type PaginationResult } from '../../shared/pagination-result.ts';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport { checkDocsDrift } from '../drift.ts';\nimport { resolveDriftMode } from '../query-options.ts';\nimport type { PaginationConfig, PaginationCtx, PaginationDocOf } from './types.ts';\n\n/** Build the `paginateFlexible` closure from the shared pagination context. */\nexport const makePaginateFlexible = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n ctx: PaginationCtx<TClients, TDb>,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n type DocOf2<X extends C> = PaginationDocOf<TClients, TDb, X>;\n\n const { client, dbLabel, logger, opts, resolve, cachedAggregate } = ctx;\n\n const paginateFlexible = async <X extends C>(\n collection: X,\n baseFilter: FilterInput<DocOf2<X>>,\n config: PaginationConfig = {},\n ): Promise<PaginationResult<DocOf2<X>>> => {\n const normalized = normalizePageLimit(\n {\n ...(config.page !== undefined ? { page: config.page } : {}),\n ...(config.limit !== undefined ? { limit: config.limit } : {}),\n },\n config.maxLimit ?? DEFAULT_MAX_LIMIT,\n // Same default as `findMany`/`paginateCursor` — the two pagination\n // APIs used to disagree silently (10 vs 100).\n { limit: DEFAULT_FIND_LIMIT },\n );\n\n const maxOffset = config.maxOffset ?? 10_000;\n if (normalized.offset > maxOffset) {\n throw new BadRequest(\n `paginateFlexible: offset ${normalized.offset} exceeds maxOffset ${maxOffset}; use paginateCursor for deep pages`,\n );\n }\n\n const dataStages: Document[] = [\n ...(config.prePipeline ?? []),\n ...(config.sort && Object.keys(config.sort).length > 0 ? [{ $sort: config.sort }] : []),\n { $skip: normalized.offset },\n { $limit: normalized.limit },\n ...(config.projection !== undefined ? [{ $project: config.projection }] : []),\n ...(config.postPipeline ?? []),\n ];\n\n const pipeline: Document[] = [\n { $match: baseFilter },\n {\n $facet: {\n data: dataStages,\n totalCount: [{ $count: 'count' }],\n },\n },\n ];\n\n return cachedAggregate<X, PaginationResult<DocOf2<X>>>({\n collection,\n opName: 'mongo.paginateFlexible',\n pipeline,\n ...(config.queryOptions !== undefined ? { options: config.queryOptions } : {}),\n execute: async (r) => {\n const aggOptions = {\n ...(r.driverOpts as Record<string, unknown>),\n ...(r.sdk.session !== undefined ? { session: r.sdk.session } : {}),\n ...(r.sdk.maxTimeMS !== undefined ? { maxTimeMS: r.sdk.maxTimeMS } : {}),\n ...(r.sdk.hint !== undefined ? { hint: r.sdk.hint } : {}),\n ...(r.sdk.batchSize !== undefined ? { batchSize: r.sdk.batchSize } : {}),\n } as AggregateOptions & Abortable;\n const rows = await client\n .collection<Document>(resolve(String(collection)))\n .aggregate(pipeline, aggOptions)\n .toArray();\n const row = rows[0] as\n | { data?: DocOf2<X>[]; totalCount?: Array<{ count: number }> }\n | undefined;\n const data = row?.data ?? [];\n const totalCount = row?.totalCount?.[0]?.count ?? 0;\n checkDocsDrift(\n {\n logger,\n db: dbLabel,\n drift: resolveDriftMode(config.queryOptions?.drift, opts.drift),\n ...(opts.getSchema !== undefined ? { getSchema: opts.getSchema } : {}),\n partial: config.projection !== undefined,\n },\n String(collection),\n 'mongo.paginateFlexible',\n data as Document[],\n );\n return buildPaginationResult(data, totalCount, normalized.page, normalized.limit);\n },\n });\n };\n\n return { paginateFlexible };\n};\n","/**\n * Pagination op factory — `makePaginationOps`. Composes the two pagination\n * strategies into one op set per database:\n *\n * - `./offset.ts` — `paginateFlexible` (single `$facet` round-trip, with totals)\n * - `./cursor.ts` — `paginateCursor` (keyset / cursor, O(log n) per page)\n *\n * Both share a small context (`./types.ts`) built here.\n */\nimport type { Db } from 'mongodb';\nimport type { DbClientsDefinition, ExtractCollectionNames, ExtractDbNames } from '../../types.ts';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { createCachedAggregate } from '../aggregation/cached-read.ts';\nimport { makeOpDeps } from '../op-deps.ts';\nimport { makePaginateCursor } from './cursor.ts';\nimport { makePaginateFlexible } from './offset.ts';\nimport type { PaginationCtx, PaginationOpsOptions } from './types.ts';\n\n/**\n * Pagination ops for one database: `paginateFlexible` (offset, `$facet`) and\n * `paginateCursor` (keyset). Both are collection-name first and schema-typed.\n * `paginateFlexible` routes through the shared cached-aggregation runner\n * (write-through cache + dedup); `paginateCursor` is a find-based keyset read\n * and stays uncached (its opaque cursor pages are largely unique).\n */\nexport const makePaginationOps = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n client: Db,\n dbLabel: string,\n logger: LoggerLike,\n opts: PaginationOpsOptions,\n) => {\n type C = ExtractCollectionNames<TClients, TDb>;\n\n const resolve = opts.resolveCollectionName;\n const deps = makeOpDeps<C>(\n logger,\n dbLabel,\n resolve,\n opts.wrapMongoErrors === true,\n opts.debugQuery,\n );\n\n const ctx: PaginationCtx<TClients, TDb> = {\n client,\n dbLabel,\n logger,\n opts,\n resolve,\n deps,\n cachedAggregate: createCachedAggregate<C>({ client, deps, opts, resolve }),\n };\n\n return {\n ...makePaginateFlexible<TClients, TDb>(ctx),\n ...makePaginateCursor<TClients, TDb>(ctx),\n };\n};\n\n// Re-export the public pagination types so the folder barrel matches the old\n// single-module exports.\nexport type {\n CursorPage,\n CursorPaginationConfig,\n PaginationConfig,\n PaginationOpsOptions,\n} from './types.ts';\n","import type { CreateCollectionOptions, Db, Document } from 'mongodb';\nimport { type ObjectField, toMongoValidator } from '../schema/index.ts';\nimport type { IndexSpec } from '../types.ts';\nimport { stableStringify } from '../utils/hash.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\n\nexport interface CollectionRegistryEntry {\n schema?: ObjectField;\n indexes?: IndexSpec[];\n}\n\n/** What `syncIndexes` changed on a collection. */\nexport interface SyncIndexesResult {\n /** Names of indexes that were created (missing declared indexes). */\n created: string[];\n /** Names of indexes that were dropped (undeclared, excluding `_id_`). */\n dropped: string[];\n}\n\n/**\n * Canonical key signature for comparing index definitions. Key ORDER is\n * significant server-side (a compound index's prefix determines which sorts\n * it supports), so `{ userId: 1, createdAt: -1 }` and\n * `{ createdAt: -1, userId: 1 }` are DIFFERENT indexes. Relevant options are\n * folded into the signature so a declared-unique index never silently matches\n * an existing non-unique one. Both sides pass through the same projection:\n * server-reported index documents carry extra fields (`v`, `ns`, …) that must\n * not leak into the comparison.\n */\ntype IndexOptionLike = Document;\n\nconst optionSignature = (options?: IndexOptionLike): string => {\n const normalized: Document = {\n unique: Boolean(options?.unique),\n sparse: Boolean(options?.sparse),\n hidden: Boolean(options?.hidden),\n expireAfterSeconds:\n typeof options?.expireAfterSeconds === 'number' ? options.expireAfterSeconds : null,\n };\n for (const key of [\n 'partialFilterExpression',\n 'collation',\n 'wildcardProjection',\n 'weights',\n 'default_language',\n 'language_override',\n 'textIndexVersion',\n '2dsphereIndexVersion',\n 'bits',\n 'min',\n 'max',\n 'bucketSize',\n 'storageEngine',\n ]) {\n if (options?.[key] !== undefined) normalized[key] = options[key];\n }\n return stableStringify(normalized);\n};\n\nconst indexKeyOf = (key: Document, options?: IndexOptionLike): string =>\n `${JSON.stringify(Object.keys(key).map((k) => [k, key[k]]))}|${optionSignature(options)}`;\n\nexport interface SchemaOpsOptions {\n resolveCollectionName: (logical: string) => string;\n getDefinition: (logical: string) => CollectionRegistryEntry | undefined;\n}\n\n/**\n * Schema-first collection management.\n *\n * `createSchema` is IDEMPOTENT and SELF-RECONCILING: on a NEW collection it\n * provisions the `$jsonSchema` validator derived from the ORM schema plus the\n * declared indexes; when the collection ALREADY exists it upgrades the DB\n * schema to match the current ORM schema — hot-swapping the validator via\n * `collMod` only when it has actually drifted, and creating any newly-declared\n * indexes. It never drops indexes or data (destructive reconciliation stays\n * explicit via `syncIndexes`), so it is safe to call on every boot: the Mongo\n * schema follows the app schema automatically as models change.\n *\n * `updateSchema` hot-swaps a validator explicitly (via `collMod`);\n * `syncIndexes` reconciles index drift (create missing, drop undeclared).\n */\nexport const makeSchemaOps = (client: Db, _logger: LoggerLike, opts: SchemaOpsOptions) => {\n /** Read validation settings currently installed on a physical collection. */\n const readCollectionValidation = async (\n physical: string,\n ): Promise<{ validator?: Document; validationLevel?: string; validationAction?: string }> => {\n const info = (await client.listCollections({ name: physical }).next()) as\n | { options?: Document }\n | undefined;\n return info?.options ?? {};\n };\n\n /**\n * Create any declared index that is missing from the live collection.\n * ADDITIVE ONLY — never drops an existing (possibly undeclared) index; that\n * stays the explicit job of `syncIndexes`.\n */\n const ensureDeclaredIndexes = async (\n collection: string,\n physical: string,\n def?: CollectionRegistryEntry,\n ): Promise<void> => {\n const declared = def?.indexes ?? [];\n if (declared.length === 0) return;\n const handle = client.collection(physical);\n const existing = new Set(\n (await handle.listIndexes().toArray())\n .filter((i) => i.name !== '_id_')\n .map((i) => indexKeyOf(i.key as Document, i as IndexOptionLike)),\n );\n for (const index of declared) {\n if (existing.has(indexKeyOf(index.key as Document, index.options))) continue;\n try {\n await handle.createIndex(index.key as Document, index.options);\n } catch (err) {\n if ([85, 86].includes((err as { code?: number })?.code ?? -1)) {\n // An index with the same name/key exists but with different options\n // (e.g. `unique` added). Can't be applied additively — tell the user\n // how to reconcile instead of failing the whole boot.\n throw new Error(\n `Cannot apply declared index on \"${collection}\": an index with the same ` +\n `name/key already exists with different options. Run ` +\n `db.syncIndexes(\"${collection}\") to reconcile index drift.`,\n { cause: err },\n );\n }\n throw err;\n }\n }\n };\n\n /**\n * Provision a collection with its `$jsonSchema` validator + declared indexes,\n * or — when the collection already exists — reconcile it to the current\n * schema (validator hot-swap + missing declared indexes). Idempotent: safe to\n * call on every boot.\n */\n const createSchema = async (\n collection: string,\n createCollectionOptions?: CreateCollectionOptions,\n ): Promise<void> => {\n const physical = opts.resolveCollectionName(collection);\n const def = opts.getDefinition(collection);\n // Caller options FIRST, derived validator LAST — a stale `validator`\n // key in the options must not clobber the schema-derived one.\n const createOptions = {\n ...(createCollectionOptions ?? {}),\n ...(def?.schema ? { validator: toMongoValidator(def.schema) } : {}),\n } as CreateCollectionOptions;\n\n // Try the fast path first: create the collection (implicitly creating its\n // database). We intentionally skip a pre-flight `listCollections` — on a\n // not-yet-created database that errors with `NamespaceNotFound` (code 26).\n // Code 48 means a previous boot already provisioned the collection, in\n // which case we fall through to the reconcile path below.\n let created = true;\n try {\n await client.createCollection(physical, createOptions);\n } catch (err) {\n if ((err as { code?: number })?.code !== 48) throw err;\n created = false;\n }\n\n if (created) {\n // Never drop the collection on index failure: another process may already\n // have written to it. The next createSchema call retries missing indexes.\n await ensureDeclaredIndexes(collection, physical, def);\n return;\n }\n\n // Collection already exists → self-heal to the current app schema: swap the\n // validator only when it actually drifted, and create any missing declared\n // indexes (never dropping anything — that is `syncIndexes`'s job).\n if (createOptions.validator) {\n const current = await readCollectionValidation(physical);\n const collMod: Document = {};\n if (stableStringify(current.validator) !== stableStringify(createOptions.validator)) {\n collMod.validator = createOptions.validator;\n }\n for (const key of ['validationLevel', 'validationAction'] as const) {\n const requested = createOptions[key];\n if (requested !== undefined && current[key] !== requested) collMod[key] = requested;\n }\n if (Object.keys(collMod).length > 0) {\n await client.command({ collMod: physical, ...collMod });\n }\n }\n await ensureDeclaredIndexes(collection, physical, def);\n };\n\n /** Hot-swap a collection's validator via `collMod` (no downtime). */\n const updateSchema = async (collection: string, schema?: ObjectField): Promise<void> => {\n const physical = opts.resolveCollectionName(collection);\n const def = opts.getDefinition(collection);\n const resolved = schema ?? def?.schema;\n if (!resolved) {\n throw new Error(`No schema available for collection \"${collection}\"`);\n }\n await client.command({\n collMod: physical,\n validator: toMongoValidator(resolved),\n });\n if (def) def.schema = resolved;\n };\n\n /**\n * Reconcile a collection's real indexes with the declared ones: create any\n * missing declared index and drop any undeclared one (`_id_` is always kept).\n * Matching compares key ORDER and all supported MongoDB index options.\n * Option-divergent same-key/name indexes are replaced during this explicit op.\n * CAUTION: indexes on shared collections created by OTHER services are\n * treated as undeclared here — list them in the definition or don't share.\n * Expects the collection to already exist (`createSchema` first). Returns\n * the created/dropped index names.\n */\n const syncIndexes = async (collection: string): Promise<SyncIndexesResult> => {\n const physical = opts.resolveCollectionName(collection);\n const def = opts.getDefinition(collection);\n const declared = def?.indexes ?? [];\n const handle = client.collection(physical);\n const existing = (await handle.listIndexes().toArray()).filter((i) => i.name !== '_id_');\n const existingByKey = new Map(\n existing.map((i) => [indexKeyOf(i.key as Document, i as IndexOptionLike), i.name as string]),\n );\n const declaredByKey = new Map(\n declared.map((d) => [indexKeyOf(d.key as Document, d.options), d]),\n );\n const keyPattern = (key: Document): string => JSON.stringify(Object.entries(key));\n const dropped: string[] = [];\n const droppedNames = new Set<string>();\n\n // MongoDB cannot replace an index's options in place. Drop conflicting\n // same-key/same-name indexes before creating the declared replacement.\n for (const spec of declaredByKey.values()) {\n const signature = indexKeyOf(spec.key as Document, spec.options);\n if (existingByKey.has(signature)) continue;\n for (const index of existing) {\n const name = index.name as string;\n if (droppedNames.has(name)) continue;\n const sameName = spec.options?.name !== undefined && index.name === spec.options.name;\n if (sameName || keyPattern(index.key as Document) === keyPattern(spec.key as Document)) {\n await handle.dropIndex(name);\n droppedNames.add(name);\n dropped.push(name);\n }\n }\n await handle.createIndex(spec.key as Document, spec.options);\n }\n\n for (const [signature, name] of existingByKey) {\n if (!declaredByKey.has(signature) && !droppedNames.has(name)) {\n await handle.dropIndex(name);\n dropped.push(name);\n }\n }\n\n const after = (await handle.listIndexes().toArray()).filter((i) => i.name !== '_id_');\n const afterByKey = new Map(\n after.map((i) => [indexKeyOf(i.key as Document, i as IndexOptionLike), i.name as string]),\n );\n const created = [...declaredByKey]\n .filter(([signature]) => !existingByKey.has(signature))\n .map(\n ([signature, spec]) =>\n spec.options?.name ?? afterByKey.get(signature) ?? JSON.stringify(spec.key),\n );\n return { created, dropped };\n };\n\n return { createSchema, updateSchema, syncIndexes };\n};\n","import { randomUUID } from 'node:crypto';\nimport type {\n ClientSession,\n Db,\n MongoClient,\n TransactionOptions as MongoTransactionOptions,\n} from 'mongodb';\nimport { InfraError, isTransactionUnsupportedError, mapMongoDriverError } from '../errors/index.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\n\nexport interface TransactionOptions extends MongoTransactionOptions {\n /** Explicitly permit non-atomic execution when transactions are unsupported. */\n allowNonTransactionalFallback?: boolean;\n}\n\nexport interface TransactionOpsOptions {\n migrationCollectionPhysical: string;\n wrapMongoErrors?: boolean;\n allowNonTransactionalFallback?: boolean;\n}\n\n/** Transaction + fenced idempotent-migration ops for one database handle. */\nexport const makeTransactionOps = (\n client: MongoClient,\n handle: Db,\n logger: LoggerLike,\n _config: Record<string, unknown>,\n opts: TransactionOpsOptions,\n) => {\n let warnedUnsupported = false;\n let journalIndexReady = false;\n const MIGRATE_LEASE_MS = 120_000;\n\n const transaction = async <T>(\n fn: (session: ClientSession | null) => Promise<T>,\n options: TransactionOptions = {},\n ): Promise<T> => {\n const { allowNonTransactionalFallback, ...driverOptions } = options;\n const allowFallback =\n allowNonTransactionalFallback ?? opts.allowNonTransactionalFallback ?? false;\n const session = client.startSession();\n try {\n return await session.withTransaction(async () => fn(session), driverOptions);\n } catch (err) {\n if (isTransactionUnsupportedError(err)) {\n if (!allowFallback) {\n if (opts.wrapMongoErrors) {\n throw new InfraError(\n 'TRANSACTIONS_UNSUPPORTED',\n 'MongoDB deployment does not support transactions; enable allowNonTransactionalFallback to run non-atomically',\n { db: handle.databaseName, op: 'transaction' },\n );\n }\n throw err;\n }\n if (!warnedUnsupported) {\n warnedUnsupported = true;\n logger.warn?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'transactions unsupported; running explicitly requested non-transactional fallback',\n );\n }\n return fn(null);\n }\n if (opts.wrapMongoErrors) {\n throw mapMongoDriverError(err, { db: handle.databaseName, op: 'transaction' });\n }\n throw err;\n } finally {\n await session.endSession().catch(() => {});\n }\n };\n\n const migrate = async (\n name: string,\n fn: (session: ClientSession | null) => Promise<void>,\n filePath?: string,\n options: { allowNonTransactionalFallback?: boolean } = {},\n ): Promise<void> => {\n const journal = handle.collection<{\n name: string;\n appliedAt: Date;\n status?: string;\n file?: string;\n expiresAt?: Date;\n claimId?: string;\n }>(opts.migrationCollectionPhysical);\n\n if (!journalIndexReady) {\n await journal.createIndex({ name: 1 }, { unique: true });\n journalIndexReady = true;\n }\n\n const isDupKeyError = (err: unknown): boolean => {\n const code = (err as { code?: number } | null)?.code;\n if (code === 11000 || code === 11001) return true;\n return /E11000 duplicate key/.test(String((err as Error | null)?.message ?? ''));\n };\n\n await transaction(async (session) => {\n const sessionOpts = session ? { session } : {};\n const now = new Date();\n const expiresAt = new Date(Date.now() + MIGRATE_LEASE_MS);\n const claimId = randomUUID();\n\n const stole = (await journal.findOneAndUpdate(\n {\n name,\n status: { $exists: true, $nin: ['applied', 'rolling_back'] },\n $or: [\n { expiresAt: { $lt: now } },\n {\n expiresAt: { $exists: false },\n appliedAt: { $lt: new Date(now.getTime() - MIGRATE_LEASE_MS) },\n },\n ],\n },\n {\n $set: {\n status: 'running',\n appliedAt: now,\n expiresAt,\n claimId,\n ...(filePath ? { file: filePath } : {}),\n },\n },\n { returnDocument: 'before', ...sessionOpts },\n )) as Document | null;\n if (stole !== null) {\n await runClaimed(session, claimId);\n return;\n }\n\n try {\n await journal.insertOne(\n {\n name,\n appliedAt: now,\n status: 'running',\n expiresAt,\n claimId,\n ...(filePath ? { file: filePath } : {}),\n },\n sessionOpts,\n );\n } catch (err) {\n if (!isDupKeyError(err)) throw err;\n const existing = (await journal.findOne(\n { name },\n { projection: { status: 1 }, ...sessionOpts },\n )) as Document | null;\n const status = existing?.status;\n if (status === undefined || status === 'applied') {\n logger.info({ name }, 'migration already applied, skipping');\n } else {\n logger.warn({ name }, 'migration claim held by another runner, skipping');\n }\n return;\n }\n await runClaimed(session, claimId);\n }, options);\n\n async function runClaimed(session: ClientSession | null, claimId: string): Promise<void> {\n const sessionOpts = session ? { session } : {};\n const heartbeat =\n session === null\n ? setInterval(() => {\n void journal\n .updateOne(\n { name, claimId, status: 'running' },\n { $set: { expiresAt: new Date(Date.now() + MIGRATE_LEASE_MS) } },\n )\n .catch(() => {});\n }, MIGRATE_LEASE_MS / 2)\n : undefined;\n heartbeat?.unref?.();\n try {\n await fn(session);\n const res = await journal.updateOne(\n { name, claimId, status: 'running' },\n { $set: { status: 'applied' }, $unset: { expiresAt: '', claimId: '' } },\n sessionOpts,\n );\n if (res.matchedCount === 0) {\n throw new Error(`Migration \"${name}\" lost its claim before it could be marked applied`);\n }\n } catch (err) {\n await journal.deleteOne({ name, claimId, status: 'running' }, sessionOpts).catch(() => {});\n throw err;\n } finally {\n if (heartbeat !== undefined) clearInterval(heartbeat);\n }\n }\n };\n\n return { transaction, migrate };\n};\n\ntype Document = Record<string, unknown>;\n","/**\n * Per-database manager assembly. `buildManager` is the composition point of the\n * op-factory pattern: it builds the collection registry (schema/hooks/\n * timestamps), resolves logical→physical names, and **spreads** every\n * `make*Ops` factory into one `CollectionManager` object per database.\n *\n * The `CollectionManager` type mirrors that spread as an intersection so both\n * the runtime value and its type stay in sync from a single source.\n */\nimport type { Db, Document, MongoClient } from 'mongodb';\nimport type { InFlight } from '../cache/in-flight.ts';\nimport type { QueryCache } from '../cache/query-cache.ts';\nimport { BadRequest } from '../errors/index.ts';\nimport type { HooksRegistry } from '../hooks/hooks.ts';\nimport { makePopulator, type PopulateOptions } from '../relation/populate.ts';\nimport type { JoinedFields, RelationDef, ValidRelation } from '../relation/relation.ts';\nimport type { DriftMode } from '../schema/validate-doc/index.ts';\nimport type { CollectionLike, DbClientsDefinition } from '../types.ts';\nimport { asCollectionDefinition, type ExtractDbNames } from '../types.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\nimport { makeAggregationOps } from './aggregation/index.ts';\nimport type { CacheInvalidationRef } from './cache-invalidation.ts';\nimport { createResolveCollectionName } from './collection-name.ts';\nimport type { CrudOps, TimestampsByCollection } from './crud/index.ts';\nimport { makeCrudOps } from './crud/index.ts';\nimport { makePaginationOps } from './pagination/index.ts';\nimport { makeSchemaOps } from './schema-ops.ts';\nimport { makeTransactionOps } from './transaction.ts';\n\n/** Everything `buildManager` needs from the composition root. */\nexport interface BuildManagerDeps<TClients extends DbClientsDefinition> {\n dbClients: TClients;\n config: { defaultDb: string; migrationDir: string; appName: string };\n logger: LoggerLike;\n sharedCache?: QueryCache;\n dedupeReads: boolean;\n inFlight: InFlight;\n wrapMongoErrors: boolean;\n debugQuery?: import('./trace-db-op.ts').DebugQuery | null;\n allowNonTransactionalFallback?: boolean;\n validateWrites?: boolean;\n drift?: DriftMode;\n /** Watch refs for cache-invalidation (physical names) — pushed to as managers build. */\n collectionRefs: CacheInvalidationRef[];\n /** The shared `db` record (sibling managers reference each other cross-DB). */\n db: Record<string, unknown>;\n}\n\n/** One collection manager per connected DB — the ORM's primary surface. */\nexport type CollectionManager<\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n> = CrudOps<TClients, TDb> &\n ReturnType<typeof makePaginationOps<TClients, TDb>> &\n ReturnType<typeof makeAggregationOps<TClients, TDb>> &\n ReturnType<typeof makeSchemaOps> &\n ReturnType<typeof makeTransactionOps> & {\n /**\n * DataLoader-backed relation population (kills N+1). Each relation is\n * validated against the schema registry (`collection` / `localField` /\n * `foreignField` / `through`), and the joined `as` fields are typed.\n */\n populate: <const T extends Document, const R extends readonly RelationDef[]>(\n docs: T[],\n relations: R & { [K in keyof R]: ValidRelation<TClients, TDb, T, R[K]> },\n options?: PopulateOptions,\n ) => Promise<Array<T & JoinedFields<TClients, TDb, R>>>;\n /** Raw `db()` handle escape hatch. */\n client: Db;\n /** Raw pooled client for host integrations (e.g. command monitoring). */\n mongoClient: MongoClient;\n /** Reference to sibling managers (cross-DB). */\n db: Record<string, unknown>;\n };\n\n/** Assemble one database's `CollectionManager` from the shared deps. */\nexport const buildManager = <\n TClients extends DbClientsDefinition,\n TDb extends ExtractDbNames<TClients>,\n>(\n deps: BuildManagerDeps<TClients>,\n dbKey: TDb,\n dbName: string,\n client: MongoClient,\n cacheNamespace = '',\n): CollectionManager<TClients, TDb> => {\n const { dbClients, config, logger, sharedCache, dedupeReads, inFlight, collectionRefs } = deps;\n const definition = dbClients[dbKey]!;\n const handle = client.db(dbName);\n const baseResolveCollectionName = createResolveCollectionName(definition);\n\n // Normalize each collection: schema-or-definition → { schema, indexes, hooks }.\n const registry = new Map<string, ReturnType<typeof asCollectionDefinition>>();\n const hooks: HooksRegistry = {};\n const timestamps: TimestampsByCollection = {};\n for (const [logical, value] of Object.entries(definition.collections)) {\n const def = asCollectionDefinition(value as CollectionLike);\n registry.set(logical, def);\n hooks[logical] = def.hooks as HooksRegistry[string];\n if (def.timestamps) timestamps[logical] = def.timestamps;\n // Cache-invalidation watchers track the PHYSICAL name (that's what cache\n // keys use), so writes to the raw collection invalidate the right reads.\n collectionRefs.push({\n db: handle,\n collection: baseResolveCollectionName(logical),\n namespace: cacheNamespace,\n });\n }\n const getDefinition = (logical: string) => registry.get(logical);\n\n // Fail fast with a clear message on unknown collection names. The type\n // system rejects them at compile time; this catches plain-JS callers\n // instead of surfacing an obscure driver error (or an empty result).\n // Internal `_`-prefixed collections (e.g. the `_migrations` journal) are\n // allowed through.\n const resolveCollectionName = (logical: string): string => {\n if (!registry.has(logical) && !logical.startsWith('_')) {\n throw new BadRequest(`Unknown collection \"${logical}\"`);\n }\n return baseResolveCollectionName(logical);\n };\n\n const crud = makeCrudOps<TClients, TDb>(handle, dbName, logger, {\n resolveCollectionName,\n cacheNamespace,\n wrapMongoErrors: deps.wrapMongoErrors,\n ...(deps.debugQuery !== undefined ? { debugQuery: deps.debugQuery } : {}),\n ...(sharedCache !== undefined ? { cache: sharedCache } : {}),\n dedupeReads,\n inFlight,\n hooks,\n timestamps,\n ...(deps.validateWrites !== undefined ? { validateWrites: deps.validateWrites } : {}),\n ...(deps.drift !== undefined ? { drift: deps.drift } : {}),\n ...(getDefinition !== undefined\n ? { getSchema: (logical: string) => getDefinition(logical)?.schema }\n : {}),\n });\n const pagination = makePaginationOps<TClients, TDb>(handle, dbName, logger, {\n resolveCollectionName,\n cacheNamespace,\n wrapMongoErrors: deps.wrapMongoErrors,\n ...(deps.debugQuery !== undefined ? { debugQuery: deps.debugQuery } : {}),\n ...(deps.drift !== undefined ? { drift: deps.drift } : {}),\n ...(getDefinition !== undefined\n ? { getSchema: (logical: string) => getDefinition(logical)?.schema }\n : {}),\n ...(sharedCache !== undefined ? { cache: sharedCache } : {}),\n dedupeReads,\n inFlight,\n });\n const aggregation = makeAggregationOps<TClients, TDb>(handle, dbName, logger, {\n resolveCollectionName,\n cacheNamespace,\n wrapMongoErrors: deps.wrapMongoErrors,\n ...(deps.debugQuery !== undefined ? { debugQuery: deps.debugQuery } : {}),\n ...(sharedCache !== undefined ? { cache: sharedCache } : {}),\n dedupeReads,\n inFlight,\n });\n const schema = makeSchemaOps(handle, logger, { resolveCollectionName, getDefinition });\n const transactionOps = makeTransactionOps(client, handle, logger, config, {\n migrationCollectionPhysical: resolveCollectionName('_migrations'),\n wrapMongoErrors: deps.wrapMongoErrors,\n ...(deps.allowNonTransactionalFallback !== undefined\n ? { allowNonTransactionalFallback: deps.allowNonTransactionalFallback }\n : {}),\n });\n const populator = makePopulator({\n findMany: async (logical, filter, options) =>\n crud.findMany(logical as never, filter as never, {\n ...options,\n cache: options?.queryCache ?? false,\n }) as Promise<Document[]>,\n });\n const populate = (async <const T extends Document, const R extends readonly RelationDef[]>(\n docs: T[],\n relations: R & { [K in keyof R]: ValidRelation<TClients, TDb, T, R[K]> },\n options: PopulateOptions = {},\n ): Promise<Array<T & JoinedFields<TClients, TDb, R>>> => {\n const result = await populator.populate(docs, relations as unknown as RelationDef[], options);\n return result as Array<T & JoinedFields<TClients, TDb, R>>;\n }) as CollectionManager<TClients, TDb>['populate'];\n\n return {\n ...crud,\n ...pagination,\n ...aggregation,\n ...schema,\n ...transactionOps,\n populate,\n client: handle,\n mongoClient: client,\n db: deps.db,\n };\n};\n","/**\n * Service facade — the composition root. `createMongoService` wires the whole\n * ORM: it resolves config (`./config.ts`), opens pooled connections\n * (`./connection.ts`), assembles one `CollectionManager` per database\n * (`./manager.ts`), and exposes health (`./health.ts`).\n *\n * Kept deliberately thin: each concern lives in a sibling module and is only\n * composed here.\n */\nimport { type MongoClient, ObjectId } from 'mongodb';\nimport { InFlight } from '../cache/in-flight.ts';\nimport type { DbClientsDefinition, ExtractDbNames } from '../types.ts';\nimport { stableHash } from '../utils/hash.ts';\nimport type { LoggerLike } from '../utils/logger.ts';\nimport type { CacheInvalidationRef } from './cache-invalidation.ts';\nimport { CacheInvalidator } from './cache-invalidation.ts';\nimport {\n type MongoServiceConfig,\n type ResolvedServiceConfig,\n resolveRuntimeConfig,\n} from './config.ts';\nimport {\n closeConnections as closePool,\n makeConnectionFactory,\n makeGetDbUrl,\n} from './connection.ts';\nimport { createHealth, type HealthReport } from './health.ts';\nimport { buildManager, type CollectionManager } from './manager.ts';\n\nexport type MongoService<TClients extends DbClientsDefinition = DbClientsDefinition> = {\n db: {\n [K in ExtractDbNames<TClients> as `${K}Client`]: CollectionManager<TClients, K>;\n };\n /** Open the pooled MongoClients and build all managers. */\n makeConnections: (names?: (keyof TClients & string)[]) => Promise<void>;\n closeConnections: () => Promise<void>;\n /** Run `fn` over every connected manager (in parallel). */\n eachDb: <T>(fn: (manager: unknown, dbKey: string) => Promise<T>) => Promise<T[]>;\n /** Ping every connected database and report per-DB health. */\n health: () => Promise<HealthReport>;\n getDbUrl: (name: string) => string;\n config: { defaultDb: string; migrationDir: string; appName: string };\n logger: LoggerLike;\n ObjectId: typeof ObjectId;\n};\n\n/**\n * Assemble the ORM service from a client definition:\n *\n * const service = createMongoService({\n * primary: {\n * name: 'app',\n * dbUrl: process.env.MONGO_URL,\n * collectionPrefix: process.env.DB_PREFIX,\n * collections: { users: userSchema, orders: { schema: orderSchema, indexes: [...] } },\n * },\n * });\n * await service.makeConnections();\n * const users = service.db.primaryClient;\n * await users.insertOne('users', { email });\n * const page = await users.paginateFlexible('users', {}, { page: 1, limit: 20 });\n */\nexport const createMongoService = <TClients extends DbClientsDefinition = DbClientsDefinition>(\n dbClients: TClients,\n configOverrides: MongoServiceConfig = {},\n): MongoService<TClients> => {\n const runtime: ResolvedServiceConfig = resolveRuntimeConfig(configOverrides);\n const { config, logger, sharedCache, dedupeReads } = runtime;\n\n const db: Record<string, unknown> = {};\n const openedClients = new Map<string, MongoClient>();\n const inFlight = new InFlight();\n const getDbUrl = makeGetDbUrl(dbClients, config);\n // Optional change-stream invalidation of the shared cache (external writers).\n const collectionRefs: CacheInvalidationRef[] = [];\n const cacheInvalidator =\n sharedCache !== undefined && configOverrides.cacheWatch === true\n ? new CacheInvalidator({ cache: sharedCache, logger })\n : undefined;\n\n const baseMakeConnections = makeConnectionFactory(\n dbClients,\n db,\n getDbUrl,\n ((key: string, dbName: string, client: MongoClient) =>\n buildManager(\n {\n dbClients,\n config,\n logger,\n ...(sharedCache !== undefined ? { sharedCache } : {}),\n dedupeReads,\n inFlight,\n wrapMongoErrors: runtime.wrapMongoErrors,\n ...(configOverrides.debugQuery !== undefined\n ? { debugQuery: configOverrides.debugQuery }\n : {}),\n ...(configOverrides.allowNonTransactionalFallback !== undefined\n ? { allowNonTransactionalFallback: configOverrides.allowNonTransactionalFallback }\n : {}),\n ...(configOverrides.validateWrites !== undefined\n ? { validateWrites: configOverrides.validateWrites }\n : {}),\n ...(configOverrides.drift !== undefined ? { drift: configOverrides.drift } : {}),\n collectionRefs,\n db,\n },\n key as ExtractDbNames<TClients>,\n dbName,\n client,\n stableHash(getDbUrl(key)),\n )) as (dbKey: string, dbName: string, client: MongoClient) => unknown,\n openedClients,\n );\n let lifecycle = Promise.resolve();\n const serializeLifecycle = <T>(operation: () => Promise<T>): Promise<T> => {\n const result = lifecycle.then(operation, operation);\n lifecycle = result.then(\n () => {},\n () => {},\n );\n return result;\n };\n\n const makeConnections = (names?: (keyof TClients & string)[]): Promise<void> =>\n serializeLifecycle(async () => {\n await baseMakeConnections(names);\n await cacheInvalidator?.start(collectionRefs);\n });\n const closeConnections = (): Promise<void> =>\n serializeLifecycle(async () => {\n await cacheInvalidator?.stop();\n collectionRefs.length = 0;\n try {\n await closePool(openedClients);\n } finally {\n for (const key of Object.keys(db)) delete db[key];\n }\n });\n\n const eachDb = async <T>(fn: (manager: unknown, dbKey: string) => Promise<T>): Promise<T[]> => {\n return Promise.all(Object.keys(db).map((key) => fn(db[key], key.replace(/Client$/, ''))));\n };\n\n const health = createHealth(db);\n\n return {\n db: db as MongoService<TClients>['db'],\n makeConnections,\n closeConnections,\n eachDb,\n health,\n getDbUrl,\n config,\n logger,\n ObjectId,\n };\n};\n\nexport type { CacheInvalidationRef } from './cache-invalidation.ts';\nexport { CacheInvalidator } from './cache-invalidation.ts';\nexport type { ResolvedServiceConfig } from './config.ts';\n// Re-export the public service surface so `service/index.ts` remains the single\n// import site (matches the pre-refactor exports; the barrel re-exports these).\nexport { type MongoServiceConfig, resolveCache } from './config.ts';\nexport { createHealth, type DbHealthResult, type HealthReport } from './health.ts';\nexport { type BuildManagerDeps, buildManager, type CollectionManager } from './manager.ts';\nexport type { DebugQuery } from './trace-db-op.ts';\nexport type { TransactionOptions } from './transaction.ts';\n","import type { Document, Filter } from 'mongodb';\n\nconst isOperatorDoc = (value: unknown): value is Document =>\n value !== null && typeof value === 'object' && !Array.isArray(value);\n\n/**\n * Merge multiple Mongo filters into one. Empty/undefined parts are skipped.\n *\n * Conflicting keys deep-merge when BOTH sides are plain objects (operator\n * documents like `{ $gte: 18 }` / `{ $in: [...] }`), so\n * `merge({ role: 'admin', age: { $gte: 18 } }, { age: { $lte: 65 } })`\n * keeps both range clauses instead of the old shallow-assign silently\n * dropping `$gte`. Scalars replace (last write wins). Top-level `$and`/`$or`\n * arrays CONCATENATE — dropping a sibling branch would change semantics.\n */\nexport const mergeMongoFilters = <T extends Document>(\n ...parts: Array<Filter<T> | undefined>\n): Filter<T> => {\n const out: Document = {};\n for (const part of parts) {\n if (!part) continue;\n for (const [key, value] of Object.entries(part as Document)) {\n if (!(key in out)) {\n out[key] = value;\n continue;\n }\n if (key === '$and' || key === '$or') {\n const prev = out[key];\n out[key] = [\n ...(Array.isArray(prev) ? prev : [prev]),\n ...(Array.isArray(value) ? value : [value]),\n ];\n continue;\n }\n const prev = out[key];\n out[key] = isOperatorDoc(prev) && isOperatorDoc(value) ? { ...prev, ...value } : value;\n }\n }\n return out as Filter<T>;\n};\n","/** Remove the `_id` field from a document (returns the same object when absent). */\nexport const stripDocumentId = <T extends Record<string, unknown>>(doc: T): Omit<T, '_id'> => {\n if (!('_id' in doc)) return doc;\n const { _id, ...rest } = doc;\n void _id;\n return rest;\n};\n\n/** Remove an arbitrary primary key field from an object. */\nexport const stripPrimaryKey = <T extends Record<string, unknown>, K extends keyof T & string>(\n patch: T,\n key: K,\n): Omit<T, K> => {\n if (!(key in patch)) return patch;\n const { [key]: _, ...rest } = patch;\n void _;\n return rest;\n};\n","import { createMongoMigrationRunner, type MongoMigrationRunner } from './migrations/index.ts';\nimport type { MongoService, MongoServiceConfig } from './service/index.ts';\nimport { createMongoService } from './service/index.ts';\nimport type { DbClientsDefinition } from './types.ts';\n\nexport interface MongoToolkitOptions extends MongoServiceConfig {}\n\n/**\n * Convenience bundle: service + migration runner sharing one config.\n *\n * const toolkit = createMongoToolkit({ primary: { name, collections } });\n * await toolkit.service.makeConnections();\n * await toolkit.migrations.up();\n */\nexport const createMongoToolkit = <TClients extends DbClientsDefinition = DbClientsDefinition>(\n dbClients: TClients,\n options: MongoToolkitOptions = {},\n): {\n service: MongoService<TClients>;\n migrations: MongoMigrationRunner;\n} => {\n const service = createMongoService(dbClients, options);\n const migrations = createMongoMigrationRunner(service, {\n migrationDir: service.config.migrationDir,\n });\n return { service, migrations };\n};\n\nexport type MongoToolkit<TClients extends DbClientsDefinition> = ReturnType<\n typeof createMongoToolkit<TClients>\n>;\n","/**\n * Generic keyed factory caches (memoization). Unlike the ORM's `QueryCache`\n * (per-collection, TTL, invalidation-aware) and `HotCache` (read-through,\n * event/timer-refreshed), these are dependency-free building blocks for\n * memoizing any expensive computation by key — including in-flight dedup so a\n * keyed factory never runs twice concurrently.\n */\nimport { LRU } from './lru.ts';\n\nexport interface CacheOptions {\n /** Max cached entries. `0` or negative → unbounded Map (default 100). */\n maxSize?: number;\n}\n\ntype BackingStore<K, V> = {\n get(k: K): V | undefined;\n set(k: K, v: V): void;\n has(k: K): boolean;\n delete(k: K): void;\n};\n\nconst makeStore = <K, V>(maxSize: number): BackingStore<K, V> => {\n if (maxSize <= 0) {\n const map = new Map<K, V>();\n return {\n get: (k) => map.get(k),\n set: (k, v) => {\n map.set(k, v);\n },\n has: (k) => map.has(k),\n delete: (k) => {\n map.delete(k);\n },\n };\n }\n return new LRU<K, V>({ max: maxSize });\n};\n\n/**\n * Synchronous keyed factory cache: one value per key, LRU-bounded.\n * Used for cheap singleton factories (connection pools, resolvers, ...).\n */\nexport const createCachedFactory = <K, V>(\n factory: (key: K) => V,\n options: CacheOptions = {},\n): ((key: K) => V) => {\n const maxSize = options.maxSize ?? 100;\n const cache = makeStore<K, V>(maxSize);\n return (key: K): V => {\n const existing = cache.get(key);\n if (existing !== undefined) return existing;\n const value = factory(key);\n cache.set(key, value);\n return value;\n };\n};\n\n/**\n * Async keyed factory cache with **in-flight deduplication**: concurrent calls\n * with the same key share a single Promise so the factory runs only once.\n * On settle (success or failure) the in-flight entry is removed.\n */\nexport const createCachedAsyncFactory = <K, V>(\n factory: (key: K) => Promise<V>,\n options: CacheOptions = {},\n): ((key: K) => Promise<V>) => {\n const maxSize = options.maxSize ?? 100;\n const cache = makeStore<K, Promise<V>>(maxSize);\n const inFlight = new Map<K, Promise<V>>();\n\n return (key: K): Promise<V> => {\n const inflight = inFlight.get(key);\n if (inflight) return inflight;\n\n const cached = cache.get(key);\n if (cached) return cached;\n\n const promise = factory(key);\n inFlight.set(key, promise);\n cache.set(key, promise);\n promise.then(\n () => {\n inFlight.delete(key);\n },\n () => {\n inFlight.delete(key);\n // Never cache a failure — evict (identity-guarded) so the next call\n // retries instead of re-surfacing the same rejected promise.\n if (cache.get(key) === promise) cache.delete(key);\n },\n );\n return promise;\n };\n};\n"]}
|