@ignex/ninox 0.1.1

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.
@@ -0,0 +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/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/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/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","canonicalKey","basename","join","options","out","isPlainObject","Decimal128","deps","SEP","buildManager","meta","s","mergeAggOptions","pipeline","opts","closeConnections"],"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/** Sleep helper used by retry backoff. */\nexport const sleep = (ms: number): Promise<void> => new Promise((r) => setTimeout(r, ms));\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 */\nexport const sleepJittered = (ms: number, jitterMs = 1000): Promise<void> =>\n sleep(ms + Math.floor(Math.random() * Math.min(ms, jitterMs)));\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 if (options.urlHint) return /replicaSet=/.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 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 9001, // SocketException\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/;\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 { name?: unknown; code?: unknown; errInfo?: unknown };\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 * 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 { isMongoDuplicateKeyError, isMongoTransientError } 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\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 return new DomainError('DUPLICATE_KEY', first.errmsg ?? '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 { ObjectId } from 'mongodb';\n\n/**\n * Deep-clone a value while preserving the BSON-ish types that\n * `JSON.parse(JSON.stringify())` would corrupt: `Date`, `ObjectId`, and\n * `RegExp`. Arrays and plain objects are copied recursively; primitives pass\n * through by reference. Used by the optional `clone` mode on `QueryCache` /\n * `HotCache` so a caller can't mutate a cached result and poison the shared\n * 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 RegExp) return new RegExp(value.source, value.flags) as T;\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' && v !== null && !Array.isArray(v);\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/** djb2 string hash → base-36 (fits comfortably in a double, no BigInt). */\nexport const hashString = (input: string): string => {\n let hash = 5381;\n for (let i = 0; i < input.length; i++) {\n hash = ((hash << 5) + hash + input.charCodeAt(i)) | 0;\n }\n return (hash >>> 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\nexport class LRU<K, V> {\n readonly max: number;\n private map = new Map<K, V>();\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 }\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 oldest = this.map.keys().next().value as K | undefined;\n if (oldest !== undefined) {\n this.map.delete(oldest);\n this.evictions++;\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 const promise = fn().finally(() => {\n this.pending.delete(key);\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 */\nimport { ObjectId } from 'mongodb';\n\n/** Approximate in-memory byte size of a cached value (used to bound single entries). */\nexport const estimateSize = (value: unknown): 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 (value instanceof ObjectId) return 16;\n if (value instanceof Date) return 8;\n if (Array.isArray(value)) return value.reduce<number>((sum, v) => sum + estimateSize(v), 0);\n if (typeof value === 'object') {\n let sum = 0;\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n sum += k.length * 2 + estimateSize(v);\n }\n return sum;\n }\n return 0;\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/** Global standalone refresh ticker. Owns the timer; stops cleanly via `stop()`. */\nexport class RefreshTicker {\n private timer?: ReturnType<typeof setInterval>;\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 /** Background refresh pass: re-run loaders for due entries, swap fresh values. */\n private tick(): void {\n const now = Date.now();\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 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 = now + q.refreshIntervalMs;\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 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 /** Raw `Db` handle (e.g. `service.db.primaryClient.client`). */\n db: Db;\n /** Physical collection name whose writes invalidate bound queries. */\n collection: string;\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\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 /** 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 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 /** 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 * 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).\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 */\nimport type { ChangeStream } from 'mongodb';\nimport type { LoggerLike } from '../../utils/logger.ts';\nimport { sleepJittered } from '../../utils/timeout.ts';\nimport { type HotCollectionRef, type RegisteredQuery, 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 /** 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/** 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\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 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 for (const q of this.host.queries().values()) {\n for (const ref of q.config.watch ?? []) {\n const key = `${ref.db.databaseName}${WATCH_SEP}${ref.collection}`;\n if (seen.has(key) || this.streams.has(key)) continue;\n seen.add(key);\n void this.watchLoop(key, ref);\n }\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 retry with backoff.\n */\n private async watchLoop(key: string, ref: HotCollectionRef): Promise<void> {\n let backoff = 0;\n while (!this.stopped) {\n try {\n const stream = ref.db.collection(ref.collection).watch([]);\n stream.on('error', () => {});\n this.streams.set(key, stream);\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 this.host.invalidateCollection(ref.collection);\n }\n } catch (err) {\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 if (/only supported on replica sets|not supported|ChangeStream/i.test(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);\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 set.add(`${ref.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).\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 * `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 * 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 type RegisteredQuery,\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>;\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 isReplica: () => this._mode === 'replica',\n fallbackToStandalone: () => {\n this._mode = 'standalone';\n if (this.refreshEnabled) this.ticker.start();\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 maxValueBytes: config.maxValueBytes,\n gen: 0,\n hits: 0,\n misses: 0,\n refreshes: 0,\n loadErrors: 0,\n sizeSkips: 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 return {\n get: (...args: TArgs) => this.get(name, ...args) as Promise<TResult>,\n invalidate: (...args: TArgs) => {\n if (args.length === 0) this.invalidate(name);\n else this.invalidateParams(name, ...args);\n },\n };\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 return 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 /** 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`, and\n * `sizeSkips` for entries dropped by `maxValueBytes`). Useful for dashboards\n * and 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 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 */\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();\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 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 void this.start().catch((err) => {\n this.logger.warn?.(\n { error: err instanceof Error ? err.message : String(err) },\n 'hot cache start failed; reads continue without auto-refresh',\n );\n });\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 const caps = await probeMongoCapabilities(ref.db);\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: ref.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 const dedupeKey = `${q.name}${WATCH_SEP}${key}`;\n return this.inflight.run<unknown>(dedupeKey, async () => {\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 if (q.maxValueBytes !== undefined && estimateSize(value) > q.maxValueBytes) {\n q.sizeSkips++;\n if (!q.warnedSize) {\n q.warnedSize = true;\n this.logger.warn?.(\n { query: q.name, bytes: estimateSize(value), 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 }\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 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 });\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\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. 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 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>>({ max: options.maxSize ?? 500 });\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 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.lru.delete(key);\n this.misses++;\n return undefined;\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 set(key: string, value: unknown, ttlMs?: number): void {\n this.sets++;\n const ttl = ttlMs ?? this.ttlMs;\n const expiresAt = ttl > 0 ? Date.now() + ttl : Infinity;\n this.lru.set(key, { value, expiresAt });\n const sep = key.indexOf(SEP);\n const collection = sep === -1 ? key : key.slice(0, sep);\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 delete(key: string): void {\n this.deletes++;\n this.lru.delete(key);\n }\n\n /** Drop every cached entry belonging to a physical collection. */\n invalidateByCollection(collection: string): void {\n const keys = this.index.get(collection);\n if (!keys) return;\n this.invalidateEvents++;\n for (const key of keys) this.lru.delete(key);\n this.index.delete(collection);\n }\n\n clear(): void {\n this.clearEvents++;\n this.lru.clear();\n this.index.clear();\n }\n}\n","import type { ClientSession } from 'mongodb';\nimport { type createMongoCapabilitiesStore, mongoTransactionsEnabled } from './capabilities.ts';\nimport { 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 the \"retryable writes\n * unsupported\" error by re-running with a null session.\n */\nexport const withGracefulMongoTransaction = async <T>(\n runner: MongoTransactionRunner,\n fn: (session: ClientSession | null) => Promise<T>,\n options: GracefulTransactionOptions = {},\n): Promise<T> => {\n const enabled =\n options.capabilities === undefined ||\n mongoTransactionsEnabled(options.capabilities, { urlHint: options.urlHint });\n if (!enabled) return fn(null);\n\n try {\n return await runner.transaction(fn);\n } catch (err) {\n const message = err instanceof Error ? err.message : '';\n if (/Transaction numbers are only allowed|transactions are not supported/i.test(message)) {\n options.logger?.warn?.({ error: message }, 'transactions unsupported, falling back');\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 */\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) return;\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 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 this.scheduled = false;\n if (this.queue.length > 0) {\n this.scheduled = true;\n queueMicrotask(() => {\n void this.flush();\n });\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 }\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(collection: string, filter: Document, update: Document): Promise<unknown>;\n findOneAndUpdate(\n collection: string,\n filter: Document,\n update: Document,\n options?: Record<string, unknown>,\n ): Promise<Document | null>;\n}\n\nexport interface MongoMigrationRunner {\n /** Apply every not-yet-applied migration in numeric order. */\n up(): Promise<void>;\n /** Roll back applied migrations in reverse order (down to `targetName` when given). */\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\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\n/** List migration files in a directory, ordered by numeric prefix. */\nexport const listMigrationFiles = async (dir: string): Promise<string[]> => {\n const files = await readdir(dir);\n return files.filter((file) => MIGRATION_FILE.test(file)).sort();\n};\n\n/** Import a migration file as `{ up, down }` + its 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 return { name: migrationNameOf(file), ...mod };\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 — claim-based bookkeeping so concurrent runners\n * can't apply the same migration twice:\n *\n * - `claim` atomically upserts a `running` row (`$setOnInsert`); the winner\n * gets `null` back from `findOneAndUpdate` and proceeds.\n * - `markApplied` flips `status` to `applied` AFTER `up()` succeeds.\n * - `cleanupStale` re-runs `running` rows left by a hard crash (>60s old).\n *\n * All operations are best-effort where the original did `.catch(() => {})`.\n */\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 /** Recover `running` rows older than a minute (hard-crash recovery). */\n cleanupStale(): Promise<void>;\n /** Atomically claim a migration. Returns true only for the winning runner. */\n claim(name: string, file: string): Promise<boolean>;\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\n/** Build the journal operations over a `JournalManager` (a connected manager). */\nexport const createMigrationJournal = (manager: JournalManager): MigrationJournal => {\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 const cleanupStale = async (): Promise<void> => {\n await manager\n .deleteMany(JOURNAL_COLLECTION, {\n status: 'running',\n appliedAt: { $lt: new Date(Date.now() - 60_000) },\n })\n .catch(() => {});\n };\n\n const claim = async (name: string, file: string): Promise<boolean> => {\n // An upsert `$setOnInsert` is exclusive at the document level — the winner\n // upserts a fresh `running` row (findOneAndUpdate returns null); any\n // concurrent runner matches the existing row and skips.\n const claimed = await manager.findOneAndUpdate(\n JOURNAL_COLLECTION,\n { name },\n {\n $setOnInsert: {\n name,\n appliedAt: new Date(),\n status: 'running',\n file,\n },\n },\n { upsert: true, returnDocument: 'before' },\n );\n return claimed === null;\n };\n\n const markApplied = async (name: string): Promise<void> => {\n await manager\n .updateOne(JOURNAL_COLLECTION, { name, status: 'running' }, { $set: { status: 'applied' } })\n .catch(async () => {\n // Marker was removed concurrently — restore an `applied` row.\n await manager\n .insertOne(JOURNAL_COLLECTION, {\n name,\n appliedAt: new Date(),\n status: 'applied',\n })\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, cleanupStale, claim, 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` — claim-based `_migrations` journal (atomic, crash-safe)\n *\n * `up()` applies pending migrations in numeric order with an atomic claim;\n * `down()` rolls back applied migrations in reverse order; `status()` reports\n * applied/pending; `create()` scaffolds a new file.\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\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\n const manager = (): JournalManager => {\n const key = Object.keys(service.db)[0];\n const db = key ? (service.db[key] as JournalManager) : undefined;\n if (!db) throw new Error('No database client connected — call service.makeConnections() first');\n return db;\n };\n\n const up = async (): Promise<void> => {\n await ensureMigrationDir(migrationDir);\n const journal = createMigrationJournal(manager());\n // Recover a claim left `running` by a hard crash: if it's older than a\n // minute it was never marked `applied`, so it can be re-run safely.\n await journal.cleanupStale();\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 // `status` flips to `applied` only AFTER `up()` succeeds, so a mid-flight\n // crash leaves a `running` row that `appliedNames()` does NOT count as\n // applied (the stale-row cleanup above re-runs it).\n if (!(await journal.claim(migration.name, basename(file)))) {\n logger.info({ name: migration.name }, 'migration already applied, skipping');\n continue;\n }\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 }\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 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 && 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 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 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 await writeFile(filePath, template, 'utf8');\n logger.info({ name, file: fileName }, 'migration scaffolded');\n return filePath;\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), with exponential backoff `delayMs * 2^attempt`. Domain errors and\n * genuine data errors are never retried.\n */\nexport const withRetry = async <T>(\n fn: () => Promise<T>,\n options: RetryOptions = {},\n _ctx?: unknown,\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 backoff = delayMs * 2 ** (attempt - 1);\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 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 * Lazy, fluent, schema-typed query builder. Nothing hits the database until an\n * executor (`one`/`many`/`cursor`/`count`/`exists`) is called. Projections via\n * `select` are pushed to the driver so only requested fields are transferred.\n *\n * await users.query('users')\n * .where({ role: 'admin' })\n * .sort({ createdAt: -1 })\n * .select(['_id', 'email'])\n * .limit(20)\n * .many();\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 /** Shallow-merge a filter into the current one (later keys win). */\n where(filter: FilterInput<TDoc>): this {\n this._filter = { ...this._filter, ...filter };\n return this;\n }\n\n /** AND-combine the current filter with a new one. */\n and(filter: FilterInput<TDoc>): this {\n this._filter = { $and: [this._filter, filter] } as FilterInput<TDoc>;\n return this;\n }\n\n /** OR-combine: current filter AND (filter1 OR filter2 ...). */\n or(...filters: Array<FilterInput<TDoc>>): this {\n this._filter = { $and: [this._filter, { $or: filters }] } as FilterInput<TDoc>;\n return this;\n }\n\n /** Set the sort order (`{ field: 1 | -1 }`). */\n sort(sort: Sort): this {\n this._sort = sort;\n return this;\n }\n\n /** Skip the first `n` matching documents. */\n skip(n: number): this {\n this._skip = n;\n return this;\n }\n\n /** Limit the result set to `n` documents. */\n limit(n: number): this {\n this._limit = n;\n return this;\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 projection: Record<string, 1> = {};\n for (const field of fields) projection[field as string] = 1;\n this._projection = projection;\n return this as unknown as QueryBuilder<TDoc, Pick<TSelection, K>>;\n }\n\n /** Raw projection document (`{ field: 1 }` / `{ field: 0 }`). */\n project(projection: Document): this {\n this._projection = projection;\n return this;\n }\n\n /** Set the index hint. */\n hint(hint: Hint): this {\n this._options.hint = hint;\n return this;\n }\n\n /** Set the driver cursor batch size. */\n batchSize(n: number): this {\n this._options.batchSize = n;\n return this;\n }\n\n /** Run the query inside a transaction session. */\n session(session: NonNullable<QueryOptions['session']>): this {\n this._options.session = session;\n return this;\n }\n\n /** Cap server-side execution time. */\n maxTimeMS(ms: number): this {\n this._options.maxTimeMS = ms;\n return this;\n }\n\n /** Bypass the read cache for this query when `false`. */\n cache(on: boolean): this {\n this._options.cache = on;\n return this;\n }\n\n /** Override in-flight dedup for this query when set. */\n dedupe(on: boolean): this {\n this._options.dedupe = on;\n return this;\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, applies batchSize). */\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. */\n async exists(): Promise<boolean> {\n return (await this.one()) !== 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(\n filter: FilterInput<Doc>,\n config: CursorPaginationConfig<Doc>,\n ): 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 ...(o ?? {}),\n ...(options.limit !== undefined ? { limit: options.limit } : {}),\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\nconst resolveItemValue = (item: NamedCollection): CollectionLike => {\n if ('schema' in item) {\n const def = item as NamedCollectionDefinition;\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 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\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 ? 'int' : 'number';\n return addNumericBounds(out, field);\n case 'double':\n out.bsonType = 'double';\n return addNumericBounds(out, field);\n case 'long':\n out.bsonType = 'long';\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 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 types.add(allInt ? '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, 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 (Decimal128-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 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);\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, 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\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 if (f.pattern) {\n try {\n if (!new RegExp(f.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 } catch {\n // Malformed pattern — nothing to enforce at runtime.\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 const ok =\n f.kind === 'decimal'\n ? value instanceof Decimal128\n : f.kind === 'long'\n ? typeof value === 'number' && Number.isInteger(value)\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\n ? new Set(['_id', ...Object.keys(ORM_RESERVED_FIELDS)])\n : new Set<string>();\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/** 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 for single-host non-replicaSet URIs\n */\nexport const normalizeMongoUrl = (rawUrl: string): string => {\n try {\n const url = new URL(rawUrl);\n if (!url.searchParams.has('retryWrites')) url.searchParams.set('retryWrites', 'false');\n const hasWriteConcern =\n url.searchParams.has('w') ||\n url.searchParams.has('wtimeoutMS') ||\n url.searchParams.has('writeConcern');\n if (!hasWriteConcern) url.searchParams.set('w', '1');\n const hostCount = url.hostname.split(',').length;\n if (\n hostCount === 1 &&\n !url.searchParams.has('replicaSet') &&\n !url.searchParams.has('directConnection')\n ) {\n url.searchParams.set('directConnection', 'true');\n }\n return url.toString();\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';\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 void this.watchLoop(key, ref);\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 try {\n const stream = ref.db.collection(ref.collection).watch([]);\n stream.on('error', () => {});\n this.streams.set(key, stream);\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 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 (/only supported on replica sets/i.test(message)) {\n // Every collection shares the same server, so one unsupported verdict\n // applies to all — disable once and stop retrying. NOTE: match ONLY\n // this definitive standalone error; replica errors like \"change stream\n // history lost\" (collection dropped) must stay 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 are not supported here (standalone?) — 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);\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 */\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 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 client = 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 interruption\n // during close) so they never surface as unhandled rejections.\n client.on('error', () => {});\n openedClients.set(dbUrl, client);\n openedThisCall.push({ url: dbUrl, client });\n await client.connect();\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 2s timeout per ping) and reports per-DB latency + overall status.\n * Types and implementation live together here so `service/index.ts` stays a\n * 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}\n\nexport interface HealthReport {\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 = (db: Record<string, unknown>) => async (): Promise<HealthReport> => {\n const started = performance.now();\n const dbs = await Promise.all(\n Object.entries(db).map(async ([key, manager]) => {\n const name = key.replace(/Client$/, '');\n const handle = (manager as { client?: Db } | undefined)?.client;\n if (!handle) return { name, ok: false };\n try {\n const t0 = performance.now();\n await withTimeout(handle.admin().command({ ping: 1 }), 2_000, `health:${name}`);\n return { name, ok: true, latencyMs: performance.now() - t0 };\n } catch {\n return { name, ok: false };\n }\n }),\n );\n return { ok: dbs.every((r) => r.ok), latencyMs: performance.now() - started, dbs };\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 maxBatchSize: options.maxBatchSize,\n 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,\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 * Mutates the source documents in place (attaching the joined value at `as`)\n * and returns them typed with the joined fields.\n *\n * const orders = await users.findMany('orders', { userId });\n * await populate(orders, [ belongsTo({ collection: 'customers', localField: 'customerId', as: 'customer' }) ]);\n * // orders[i].customer is now the joined Customer document\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 for (const relation of relations) {\n const target = relation.foreignField ?? '_id';\n const sourceKeys = distinctKeys(docs.map((doc) => (doc as Document)[relation.localField]));\n\n if (relation.type === 'belongsTo') {\n const loader = createForeignKeyLoader(deps, relation.collection, target, options);\n const values = await loader.loadMany(sourceKeys);\n const byKey = new Map(sourceKeys.map((key, i) => [canonicalKey(key), values[i]]));\n for (const doc of docs) {\n const key = (doc as Document)[relation.localField];\n const match =\n key === undefined || key === null ? undefined : byKey.get(canonicalKey(key))?.[0];\n (doc as Record<string, unknown>)[relation.as] =\n match ?? (relation.optional ? undefined : null);\n }\n } else if (relation.type === 'hasMany') {\n const loader = createForeignKeyLoader(deps, relation.collection, target, options);\n const values = await loader.loadMany(sourceKeys);\n const byKey = new Map(sourceKeys.map((key, i) => [canonicalKey(key), values[i] ?? []]));\n for (const doc of docs) {\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 throughLoader = createForeignKeyLoader(\n deps,\n relation.through.collection,\n relation.through.localField,\n options,\n );\n const throughValues = await throughLoader.loadMany(sourceKeys);\n const throughByKey = new Map(\n sourceKeys.map((key, i) => [canonicalKey(key), throughValues[i] ?? []]),\n );\n const joinDocs = throughValues.flat();\n const targetKeys = distinctKeys(\n joinDocs.map((join) => (join as Document)[relation.through.foreignField]),\n );\n\n const targetLoader = createForeignKeyLoader(deps, relation.collection, target, options);\n const targetValues = await targetLoader.loadMany(targetKeys);\n const targetByKey = new Map(\n targetKeys.map((key, i) => [canonicalKey(key), targetValues[i] ?? []]),\n );\n\n for (const doc of docs) {\n const key = (doc as Document)[relation.localField];\n const joins =\n key === undefined || key === null ? [] : (throughByKey.get(canonicalKey(key)) ?? []);\n const targets = joins.flatMap(\n (join) =>\n targetByKey.get(canonicalKey((join as Document)[relation.through.foreignField])) ??\n [],\n );\n (doc as Record<string, unknown>)[relation.as] = targets;\n }\n }\n }\n return docs as Array<T & Record<string, unknown>>;\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\nexport interface TraceDbOpOptions {\n /** Map driver errors to typed DomainError/InfraError before rethrowing. */\n wrapMongoErrors?: boolean;\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 */\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 const result = 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). */\n meta: (collection: TC, op: string) => 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): DbOpMeta => ({\n collection: String(collection),\n physicalCollection: resolve(String(collection)),\n db: dbLabel,\n op,\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 retryWrites?: boolean /**\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?:\n | DriftMode\n | boolean /** 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,\n cache,\n retryWrites,\n sdk: { session, maxTimeMS, hint, batchSize, drift },\n driverOpts: rest as Omit<T, keyof QueryOptions>,\n };\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) => 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): 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), 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 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 } 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\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 return defineCrudOp(\n this.deps.crudDeps,\n this.deps.logical,\n 'mongo.pipeline',\n (r) =>\n this.deps\n .coll()\n .aggregate<TDoc>(this.stages, this.deps.mergeDriver(r.driverOpts, r.sdk))\n .toArray(),\n this.deps.options,\n );\n }\n\n /** Run the pipeline and return the first output document (or null). */\n async first(): Promise<TDoc | null> {\n return defineCrudOp(\n this.deps.crudDeps,\n this.deps.logical,\n 'mongo.pipeline',\n async (r) => {\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 this.deps.options,\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 } = 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 );\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,\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`) and the\n * `DATE_PART_FORMATS` lookup for date-bucket `$dateToString` formats.\n */\nimport type { AggregateOptions } 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 session: sdk.session,\n maxTimeMS: sdk.maxTimeMS,\n hint: sdk.hint,\n 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 * 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 { defineCrudOp } from '../crud-op.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 { deps, coll, mergeAggOptions } = 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 defineCrudOp(\n deps,\n collection,\n 'mongo.groupBy',\n (r) =>\n coll(collection)\n .aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray(),\n options,\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 defineCrudOp(\n deps,\n collection,\n 'mongo.dateRangeAnalysis',\n (r) =>\n coll(collection)\n .aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray(),\n options,\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 { defineCrudOp } from '../crud-op.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 { deps, coll, mergeAggOptions, resolve } = 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 defineCrudOp(\n deps,\n collection,\n 'mongo.lookupJoin',\n (r) =>\n coll(collection)\n .aggregate<TResult>(pipeline, mergeAggOptions(r.driverOpts, r.sdk))\n .toArray(),\n options,\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 { defineCrudOp } from '../crud-op.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 { deps, coll, mergeAggOptions } = 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 { page: paginationConfig.page, limit: paginationConfig.limit },\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 defineCrudOp(\n deps,\n collection,\n 'mongo.textSearch',\n 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 options,\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 { 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.\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 };\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 * 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\nconst UPDATE_OPERATORS = [\n '$set',\n '$unset',\n '$inc',\n '$push',\n '$pull',\n '$addToSet',\n '$mul',\n '$min',\n '$max',\n '$rename',\n '$setOnInsert',\n '$currentDate',\n] as const;\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 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 { 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 ) => 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 ) => 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 ) => 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 ): Promise<T> => defineCrudOp(deps, collection, opName, execute, options);\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 ): Promise<T> => defineCrudOp(deps, collection, opName, execute, options, true);\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 /** Stamp `createdAt`/`updatedAt` onto a doc being created (in place, only when unset). */\n const stampCreate = (collection: ColNames<TClients, TDb>, doc: Document): void => {\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 /** 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 // 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 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 ): Promise<T> => {\n const physical = resolve(String(collection));\n const resolved = resolveQueryOptions(options);\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 { logger, db: dbLabel, drift: mode, getSchema: opts.getSchema },\n String(collection),\n opName,\n docs,\n );\n };\n\n const executeWrapped = () =>\n deps.trace(deps.meta(collection, opName), () =>\n withRetry(() => execute(resolved), {\n maxAttempts: resolved.maxAttempts,\n delayMs: resolved.retryDelayMs,\n }),\n );\n\n const key = useCache\n ? opts.cache!.key(\n cacheCollectionKey(client.databaseName, physical),\n stableHash([filter, options]),\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 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);\n return value;\n });\n }\n return fetchAndCheck();\n };\n\n if (shouldDedupe) {\n const dedupeKey = `${cacheCollectionKey(client.databaseName, physical)}|${opName}|${stableHash([filter, options])}`;\n return opts.inFlight!.run(dedupeKey, runOnce);\n }\n return 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 { client, 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 session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n hint: r.sdk.hint,\n };\n return coll(collection).findOne(toDriverFilter(f), opts) 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 session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n 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 session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n hint: r.sdk.hint,\n };\n return 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 session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n 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 );\n };\n\n /** Approximate collection count from metadata (fast, not filter-aware). */\n const estimatedDocumentCount = async <X extends C>(\n collection: X,\n options?: EstimatedDocumentCountOptions & QueryOptions,\n ): Promise<number> =>\n ctx.run(\n collection,\n 'mongo.estimatedDocumentCount',\n async (r) => {\n const opts: EstimatedDocumentCountOptions = {\n ...(r.driverOpts as EstimatedDocumentCountOptions),\n session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n };\n return coll(collection).estimatedDocumentCount(opts);\n },\n options,\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 session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n hint: r.sdk.hint,\n };\n return 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 (where documented) fire lifecycle hooks; transient\n * driver errors are retried only when the caller opts in via\n * `QueryOptions.retryWrites` (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 { 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 /** 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 session: r.sdk.session,\n };\n return coll(collection).insertOne(doc as OptionalUnlessRequiredId<DocOf2<X>>, insertOpts);\n },\n options,\n );\n invalidate(collection);\n await runHooks(opts.hooks, 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 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 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 const result = await writeRun(\n collection,\n 'mongo.insertMany',\n async (r) => {\n const bulkOpts: BulkWriteOptions = {\n ...(r.driverOpts as BulkWriteOptions),\n session: r.sdk.session,\n };\n return coll(collection).insertMany(\n docs as ReadonlyArray<OptionalUnlessRequiredId<DocOf2<X>>>,\n bulkOpts,\n );\n },\n options,\n );\n invalidate(collection);\n await runHooks(opts.hooks, 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 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 );\n invalidate(collection);\n await runHooks(opts.hooks, 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. */\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 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 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 );\n invalidate(collection);\n return result;\n };\n\n /** Find one + update atomically. Returns the updated doc (`returnDocument: 'after'` default). */\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 const effective = stampUpdate(collection, update);\n const result = await writeRun(\n collection,\n 'mongo.findOneAndUpdate',\n async (r) => {\n const fOpts: FindOneAndUpdateOptions = {\n ...(r.driverOpts as FindOneAndUpdateOptions),\n session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n hint: r.sdk.hint as FindOneAndUpdateOptions['hint'],\n // `after` is the ORM's default, but honor an explicit caller override.\n returnDocument: (r.driverOpts as FindOneAndUpdateOptions).returnDocument ?? 'after',\n };\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 );\n invalidate(collection);\n return result;\n };\n\n /** Find one + replace atomically with a full replacement doc. */\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 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: FindOneAndReplaceOptions = {\n ...(r.driverOpts as FindOneAndReplaceOptions),\n session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n hint: r.sdk.hint as FindOneAndReplaceOptions['hint'],\n // `after` is the ORM's default, but honor an explicit caller override.\n returnDocument: (r.driverOpts as FindOneAndReplaceOptions).returnDocument ?? 'after',\n };\n return coll(collection).findOneAndReplace(\n toDriverFilter(filter),\n effective,\n fOpts,\n ) as unknown as DocOf2<X> | null;\n },\n options,\n );\n invalidate(collection);\n return result;\n };\n\n /** Replace one document by filter (full replacement, not partial update). */\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 const result = await writeRun(\n collection,\n 'mongo.replaceOne',\n async (r) => {\n const repOpts: ReplaceOptions = {\n ...(r.driverOpts as ReplaceOptions),\n 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 );\n invalidate(collection);\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 session: r.sdk.session,\n };\n return coll(collection).deleteOne(toDriverFilter(filter), delOpts);\n },\n options,\n );\n invalidate(collection);\n await runHooks(opts.hooks, 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. */\n const deleteMany = async <X extends C>(\n collection: X,\n filter: FilterInput<DocOf2<X>>,\n options?: DeleteOptions & QueryOptions,\n ): Promise<DeleteResult> => {\n const result = await writeRun(\n collection,\n 'mongo.deleteMany',\n async (r) => {\n const delOpts: DeleteOptions = {\n ...(r.driverOpts as DeleteOptions),\n session: r.sdk.session,\n };\n return coll(collection).deleteMany(toDriverFilter(filter), delOpts);\n },\n options,\n );\n invalidate(collection);\n return result;\n };\n\n /** Find one + delete atomically, returning the deleted doc (or `null`). */\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 const result = await writeRun(\n collection,\n 'mongo.findOneAndDelete',\n async (r) => {\n const fOpts: FindOneAndDeleteOptions = {\n ...(r.driverOpts as FindOneAndDeleteOptions),\n session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n hint: r.sdk.hint as FindOneAndDeleteOptions['hint'],\n };\n return coll(collection).findOneAndDelete(\n toDriverFilter(filter),\n fOpts,\n ) as unknown as DocOf2<X> | null;\n },\n options,\n );\n invalidate(collection);\n return result;\n };\n\n /** Soft-delete one doc: sets `deletedAt` instead of removing it (active reads exclude it). */\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 const active = mergeMongoActiveFilter(true, filter);\n const result = await writeRun(\n collection,\n 'mongo.softDeleteOne',\n async (r) => {\n const updateOpts: UpdateOptions = {\n ...(r.driverOpts as UpdateOptions),\n session: r.sdk.session,\n };\n return coll(collection).updateOne(\n active,\n { $set: { deletedAt: new Date() } } as unknown as UpdateFilter<DocOf2<X>>,\n updateOpts,\n );\n },\n options,\n );\n invalidate(collection);\n return result;\n };\n\n /** Upsert one document (insert when the filter matches nothing). */\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 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 session: r.sdk.session,\n upsert: true,\n };\n return coll(collection).updateOne(toDriverFilter(filter), formatted, updateOpts);\n },\n options,\n );\n invalidate(collection);\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 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 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 result = await writeRun(\n collection,\n 'mongo.bulkUpsert',\n async (r) => {\n const bulkOpts: BulkWriteOptions = {\n ...(r.driverOpts as BulkWriteOptions),\n session: r.sdk.session,\n };\n return coll(collection).bulkWrite(writes, bulkOpts);\n },\n options,\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 session: r.sdk.session,\n };\n return coll(collection).bulkWrite(operations, bulkOpts);\n },\n options,\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 return new ObjectId(tagged.v as string);\n case 'date':\n return new Date(tagged.v as string);\n case 'string':\n return tagged.v as string;\n case 'number':\n return tagged.v as number;\n case 'boolean':\n return tagged.v as boolean;\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<DocOf2<X>>,\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, 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 session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n hint: r.sdk.hint,\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 );\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 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 const nextCursor =\n hasMore && boundary !== undefined\n ? encodeCursor({\n sort: config.sort,\n values: sortKeys.map(([f]) => (boundary as Document)[f]),\n })\n : null;\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 { Document } 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 { defineCrudOp } from '../crud-op.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, deps } = 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 { page: config.page, limit: config.limit },\n config.maxLimit ?? DEFAULT_MAX_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.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 defineCrudOp(\n deps,\n collection,\n 'mongo.paginateFlexible',\n async (r) => {\n const aggOptions = {\n ...(r.driverOpts as Record<string, unknown>),\n session: r.sdk.session,\n maxTimeMS: r.sdk.maxTimeMS,\n hint: r.sdk.hint,\n batchSize: r.sdk.batchSize,\n };\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 getSchema: opts.getSchema,\n },\n String(collection),\n 'mongo.paginateFlexible',\n data as Document[],\n );\n return buildPaginationResult(data, totalCount, normalized.page, normalized.limit);\n },\n config.queryOptions,\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 { 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 */\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 };\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 { DomainError } from '../errors/index.ts';\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/** Canonical key signature for comparing index definitions (order-insensitive). */\nconst indexKeyOf = (key: Document): string =>\n JSON.stringify(\n Object.keys(key)\n .sort()\n .map((k) => [k, key[k]]),\n );\n\nexport interface SchemaOpsOptions {\n resolveCollectionName: (logical: string) => string;\n getDefinition: (logical: string) => CollectionRegistryEntry | undefined;\n}\n\n/**\n * Schema-first collection management. `createSchema` provisions a collection\n * with a `$jsonSchema` validator derived from the ORM schema (and creates any\n * declared indexes); `updateSchema` hot-swaps the validator via `collMod`.\n */\nexport const makeSchemaOps = (client: Db, _logger: LoggerLike, opts: SchemaOpsOptions) => {\n /** Provision a collection with its `$jsonSchema` validator + declared indexes. */\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 const validator = def?.schema ? toMongoValidator(def.schema) : undefined;\n try {\n await client.createCollection(physical, {\n ...(validator ? { validator } : {}),\n ...(createCollectionOptions ?? {}),\n });\n } catch (err) {\n if ((err as { code?: number })?.code === 48) {\n throw new DomainError('COLLECTION_EXISTS', `Collection \"${collection}\" already exists`, {\n physicalCollection: physical,\n });\n }\n throw err;\n }\n const indexes = def?.indexes ?? [];\n if (indexes.length > 0) {\n try {\n await client.collection(physical).createIndexes(\n indexes.map((index) => ({\n key: index.key as Document,\n ...(index.options ?? {}),\n })),\n );\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 }\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 * An existing index whose KEY matches a declared one is left untouched\n * (options are not re-applied). Expects the collection to already exist\n * (`createSchema` first). Returns 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.name as string]),\n );\n const declaredByKey = new Map(declared.map((d) => [indexKeyOf(d.key as Document), d]));\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(after.map((i) => [indexKeyOf(i.key as Document), i.name as string]));\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 { 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 /**\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)`.\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 const message = err instanceof Error ? err.message : '';\n const code = (err as { code?: unknown })?.code;\n // Standalone (and deployments without retryable writes) can't run\n // transactions; fall back to running `fn(null)` non-transactionally.\n const unsupported =\n code === 20 ||\n /Transaction numbers are only allowed/i.test(message) ||\n /does not support retryable writes/i.test(message);\n if (unsupported) {\n logger.warn?.({ code }, 'transactions unsupported, falling back to non-transactional');\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: `findOneAndUpdate({ name }, $setOnInsert, upsert)`\n * returns null when we won the claim. On failure the claim is deleted so the\n * migration can be retried.\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<{ name: string; appliedAt: Date; file?: string }>(\n opts.migrationCollectionPhysical,\n );\n await transaction(async (session) => {\n const sessionOpts = session ? { session } : {};\n const claim = await journal.findOneAndUpdate(\n { name },\n {\n $setOnInsert: {\n name,\n appliedAt: new Date(),\n ...(filePath ? { file: filePath } : {}),\n },\n },\n { upsert: true, returnDocument: 'before', ...sessionOpts },\n );\n if (claim) {\n logger.info({ name }, 'migration already applied, skipping');\n return;\n }\n try {\n await fn(session);\n } catch (err) {\n await journal.deleteOne({ name }, sessionOpts).catch(() => {});\n throw err;\n }\n });\n };\n\n return { transaction, migrate };\n};\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 cache: sharedCache,\n dedupeReads,\n inFlight,\n hooks,\n timestamps,\n drift: deps.drift,\n getSchema: (logical) => getDefinition(logical)?.schema,\n });\n const pagination = makePaginationOps<TClients, TDb>(handle, dbName, logger, {\n resolveCollectionName,\n wrapMongoErrors: deps.wrapMongoErrors,\n drift: deps.drift,\n getSchema: (logical) => getDefinition(logical)?.schema,\n });\n const aggregation = makeAggregationOps<TClients, TDb>(handle, dbName, logger, {\n resolveCollectionName,\n wrapMongoErrors: deps.wrapMongoErrors,\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 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,\n dedupeReads,\n inFlight,\n wrapMongoErrors: runtime.wrapMongoErrors,\n 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\n/**\n * Merge multiple Mongo filters into one. Empty/undefined parts are skipped and\n * later keys win on shallow conflicts (mirrors sdk-db `mergeMongoFilters`).\n */\nexport const mergeMongoFilters = <T extends Document>(\n ...parts: Array<Filter<T> | undefined>\n): Filter<T> => {\n const out: Filter<T> = {};\n for (const part of parts) {\n if (!part) continue;\n Object.assign(out, part);\n }\n return out;\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"]}