@nxgt/mongo-kit 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1,18 +1,19 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/config/checks.ts", "../src/config/define-config.ts", "../src/discover.ts", "../src/kit/create-kit.ts", "../src/kit/context.ts", "../src/kit/scope.ts", "../src/kit/sync.ts", "../src/kit/transaction.ts", "../src/kit/derive.ts"],
3
+ "sources": ["../src/errors/kit-error.ts", "../src/config/checks.ts", "../src/config/define-config.ts", "../src/discover.ts", "../src/kit/create-kit.ts", "../src/kit/context.ts", "../src/kit/scope.ts", "../src/kit/sync.ts", "../src/kit/transaction.ts", "../src/kit/derive.ts"],
4
4
  "sourcesContent": [
5
- "import type { AnyCollectionDefinition } from '@nxgt/mongo';\nimport type { DatabaseConfig } from './types';\n\n/** A definition, told by its shape: `instanceof` has no class to ask. */\nexport function isDefinition(value: unknown): value is AnyCollectionDefinition {\n\tif (typeof value !== 'object' || value === null) return false;\n\tconst candidate = value as Partial<AnyCollectionDefinition>;\n\treturn (\n\t\ttypeof candidate.name === 'string' &&\n\t\ttypeof candidate.schema === 'object' &&\n\t\tcandidate.schema !== null &&\n\t\tArray.isArray(candidate.indexes) &&\n\t\ttypeof candidate.stamps === 'object'\n\t);\n}\n\n/** The definitions of a module object, under the keys they are exported by. */\nexport function definitionsOf(\n\tcollections: object,\n): [string, AnyCollectionDefinition][] {\n\treturn Object.entries(collections).filter(\n\t\t(entry): entry is [string, AnyCollectionDefinition] =>\n\t\t\tisDefinition(entry[1]),\n\t);\n}\n\nconst refuse = (where: string, said: string): never => {\n\tthrow new TypeError(`defineConfig: ${where} ${said}`);\n};\n\n/**\n * The collection options the kit decides itself: the database each collection\n * is on, the session and the actor a derived kit carries, and the sync the\n * database's `autoSync` asks for. The types refuse them in `options`, where\n * the shape is `KitCollectionOptions`; under `optionsFor` they are only\n * refused here, and one of them there would quietly outrank the kit.\n */\nconst OWNED = ['db', 'session', 'actor', 'autoSync'] as const;\n\nfunction checkOwned(where: string, what: string, options: unknown): void {\n\tif (typeof options !== 'object' || options === null) return;\n\tfor (const key of OWNED) {\n\t\tif (key in options) {\n\t\t\trefuse(\n\t\t\t\twhere,\n\t\t\t\t`has \"${key}\" in ${what}, which the kit decides: ` +\n\t\t\t\t\t'a database is named by its key, `as` and `withSession` carry the ' +\n\t\t\t\t\t\"actor and the session, and `autoSync` is the database's\",\n\t\t\t);\n\t\t}\n\t}\n}\n\n/** Everything one database's config must answer before anything connects. */\nexport function checkDatabase(\n\tname: string,\n\tconfig: DatabaseConfig<object>,\n): [string, AnyCollectionDefinition][] {\n\tconst where = `database \"${name}\"`;\n\tif (typeof config !== 'object' || config === null) {\n\t\trefuse(where, 'is not a configuration object');\n\t}\n\tconst hasUri = config.uri !== undefined;\n\tconst hasClient = config.client !== undefined;\n\tif (hasUri === hasClient) {\n\t\trefuse(\n\t\t\twhere,\n\t\t\thasUri\n\t\t\t\t? 'has both a uri and a client: pass the one it should use'\n\t\t\t\t: 'has neither a uri nor a client',\n\t\t);\n\t}\n\tif (hasUri && (typeof config.uri !== 'string' || config.uri === '')) {\n\t\trefuse(where, 'has a uri that is not a string');\n\t}\n\tif (hasClient && typeof config.client?.db !== 'function') {\n\t\trefuse(where, 'has a client that is not a MongoClient');\n\t}\n\tif (hasClient && config.clientOptions !== undefined) {\n\t\trefuse(\n\t\t\twhere,\n\t\t\t'has client options beside a client it did not open: pass them where the client is made',\n\t\t);\n\t}\n\tif (config.database !== undefined && config.database === '') {\n\t\trefuse(where, 'has an empty database name');\n\t}\n\tif (typeof config.collections !== 'object' || config.collections === null) {\n\t\trefuse(where, 'has no collections object');\n\t}\n\tconst definitions = definitionsOf(config.collections);\n\tif (definitions.length === 0) {\n\t\trefuse(\n\t\t\twhere,\n\t\t\t'has a collections object with no definition in it: pass the module, as in `import * as collections`',\n\t\t);\n\t}\n\tconst byName = new Map<string, string>();\n\tfor (const [key, definition] of definitions) {\n\t\tconst seen = byName.get(definition.name);\n\t\tif (seen !== undefined) {\n\t\t\trefuse(\n\t\t\t\twhere,\n\t\t\t\t`wires \"${seen}\" and \"${key}\" to the same collection, \"${definition.name}\"`,\n\t\t\t);\n\t\t}\n\t\tbyName.set(definition.name, key);\n\t}\n\tconst keys = new Set(definitions.map(([key]) => key));\n\tfor (const key of Object.keys(config.optionsFor ?? {})) {\n\t\tif (!keys.has(key)) {\n\t\t\trefuse(where, `has options for \"${key}\", which it does not wire`);\n\t\t}\n\t}\n\tcheckOwned(where, 'options', config.options);\n\tfor (const [key, options] of Object.entries(config.optionsFor ?? {})) {\n\t\tcheckOwned(where, `the options of \"${key}\"`, options);\n\t}\n\treturn definitions;\n}\n",
6
- "import { checkDatabase } from './checks';\nimport type {\n\tChecked,\n\tDatabaseConfig,\n\tKitConfig,\n\tKitConfigInput,\n} from './types';\n\n/** Whether the config named its databases, or is one database itself. */\nfunction databasesOf(\n\tconfig: KitConfigInput,\n): Record<string, DatabaseConfig<object>> {\n\tif (typeof config !== 'object' || config === null) {\n\t\tthrow new TypeError('defineConfig: a configuration object is required');\n\t}\n\tif (!('databases' in config)) {\n\t\treturn { default: config as DatabaseConfig<object> };\n\t}\n\tconst { databases } = config;\n\tif (typeof databases !== 'object' || databases === null) {\n\t\tthrow new TypeError('defineConfig: databases is not an object');\n\t}\n\tconst names = Object.keys(databases);\n\tif (names.length === 0) {\n\t\tthrow new TypeError('defineConfig: databases names none');\n\t}\n\treturn databases as Record<string, DatabaseConfig<object>>;\n}\n\n/**\n * The configuration of an application's MongoDB, checked once and frozen.\n *\n * ```ts\n * import * as collections from './models';\n *\n * export const config = defineConfig({\n * \turi: process.env.MONGO_URI!,\n * \tcollections,\n * });\n * ```\n *\n * Several databases name themselves:\n *\n * ```ts\n * defineConfig({\n * \tdatabases: {\n * \t\tmain: { uri: process.env.MONGO_URI!, collections },\n * \t\tanalytics: { uri: process.env.ANALYTICS_URI!, collections: events },\n * \t},\n * });\n * ```\n *\n * It connects to nothing and reads no environment variable: what is wrong\n * with the configuration throws here, where the application starts, and the\n * variables are the application's to read.\n */\nexport function defineConfig<const C extends KitConfigInput>(\n\tconfig: C & Checked<C>,\n): KitConfig<C> {\n\tconst databases = databasesOf(config);\n\tfor (const [name, database] of Object.entries(databases)) {\n\t\tcheckDatabase(name, database);\n\t}\n\treturn Object.freeze({\n\t\tdatabases: Object.freeze({ ...databases }),\n\t}) as KitConfig<C>;\n}\n",
7
- "import type { AnyCollectionDefinition } from '@nxgt/mongo';\nimport { definitionsOf, isDefinition } from './config/checks';\n\n/** What to scan, and what to read in each file it finds. */\nexport interface DiscoverOptions {\n\t/** A glob, relative to `cwd`: `'src/models/*.model.ts'`. */\n\tglob: string;\n\t/** Where the glob starts. Default: the process's working directory. */\n\tcwd?: string;\n\t/**\n\t * The export to read in each file. Default: every export that is a\n\t * definition, which is what `import * as collections` gives.\n\t */\n\texport?: string;\n}\n\n/**\n * The definitions of the files a glob matches, read at run time.\n *\n * For scripts a sync or a migration run from the repository — and for\n * nothing else: a glob is read from the file system, so it finds nothing\n * once the application is bundled, and it produces **no types**. An\n * application wires its collections with `import * as collections from\n * './models'`, which a bundler follows and the compiler sees.\n *\n * ```ts\n * import { connectMongo, syncCollections } from '@nxgt/mongo';\n * import { discoverCollections } from '@nxgt/mongo-kit';\n *\n * const mongo = await connectMongo(process.env.MONGO_URI!);\n * const definitions = await discoverCollections({ glob: 'src/**\\/*.model.ts' });\n * await syncCollections(mongo.db, definitions);\n * await mongo.close();\n * ```\n *\n * The files are imported, so their top level runs, and the glob is\n * `Bun.Glob`: this one function needs the Bun runtime.\n */\nexport async function discoverCollections(\n\toptions: DiscoverOptions,\n): Promise<AnyCollectionDefinition[]> {\n\tconst { glob, cwd = process.cwd(), export: name } = options;\n\tif (typeof glob !== 'string' || glob === '') {\n\t\tthrow new TypeError('discoverCollections: a glob is required');\n\t}\n\tconst paths = await Array.fromAsync(new Bun.Glob(glob).scan({ cwd }));\n\tconst found: AnyCollectionDefinition[] = [];\n\tconst byName = new Map<string, string>();\n\tfor (const path of paths.sort()) {\n\t\tconst module = (await import(`${cwd}/${path}`)) as Record<string, unknown>;\n\t\tconst definitions =\n\t\t\tname === undefined\n\t\t\t\t? definitionsOf(module)\n\t\t\t\t: isDefinition(module[name])\n\t\t\t\t\t? ([[name, module[name]]] as [string, AnyCollectionDefinition][])\n\t\t\t\t\t: [];\n\t\tif (name !== undefined && definitions.length === 0) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`discoverCollections: ${path} exports no definition named \"${name}\"`,\n\t\t\t);\n\t\t}\n\t\tfor (const [, definition] of definitions) {\n\t\t\tconst seen = byName.get(definition.name);\n\t\t\tif (seen !== undefined && seen !== path) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`discoverCollections: ${seen} and ${path} both define the collection \"${definition.name}\"`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tbyName.set(definition.name, path);\n\t\t\tfound.push(definition);\n\t\t}\n\t}\n\treturn found;\n}\n",
8
- "import { connectMongo, type MongoConnection } from '@nxgt/mongo';\nimport type { Db } from 'mongodb';\nimport { checkDatabase } from '../config/checks';\nimport type { DatabaseConfig, KitConfig } from '../config/types';\nimport type { DatabaseContext, KitContext } from './context';\nimport { kitOf } from './derive';\nimport type { MongoKit } from './types';\n\n/** Where one database is, and whether the kit opened it itself. */\nasync function open(\n\tconfig: DatabaseConfig<object>,\n): Promise<{ db: Db; connection: MongoConnection | undefined }> {\n\tif (config.client) {\n\t\tconst client = config.client;\n\t\treturn {\n\t\t\tdb: config.database ? client.db(config.database) : client.db(),\n\t\t\tconnection: undefined,\n\t\t};\n\t}\n\tconst connection = await connectMongo(\n\t\tconfig.uri as string,\n\t\tconfig.clientOptions,\n\t);\n\treturn {\n\t\tdb: config.database ? connection.client.db(config.database) : connection.db,\n\t\tconnection,\n\t};\n}\n\n/**\n * A key the driver's `Db` already answers to would be unreachable on the\n * scope. The types refuse it where the config is written; this asks the\n * object itself, so a member the driver adds in a later release is caught\n * here rather than silently shadowed.\n */\nfunction checkCollisions(name: string, db: Db, keys: readonly string[]): void {\n\tfor (const key of keys) {\n\t\tif (key in db) {\n\t\t\tthrow new TypeError(\n\t\t\t\t`createKit: database \"${name}\" wires a collection under \"${key}\", ` +\n\t\t\t\t\t\"which is a member of the driver's Db: it would be unreachable. \" +\n\t\t\t\t\t'Export that definition under another name.',\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Opens what the configuration describes, and gives the application its\n * collections on their database.\n *\n * ```ts\n * await using kit = await createKit(config);\n * const user = await kit.db.users.create({ email: 'ada@example.com' });\n * ```\n *\n * A database with a `uri` takes a hold on the client `connectMongo` shares\n * for that URI, and `close()` gives it back; a database given a `client` uses\n * it and never closes it. Nothing is built ahead of the connections: a\n * collection is built the first time it is read.\n */\nexport async function createKit<C>(config: KitConfig<C>): Promise<MongoKit<C>> {\n\tconst entries = Object.entries(config.databases) as [\n\t\tstring,\n\t\tDatabaseConfig<object>,\n\t][];\n\tconst databases: DatabaseContext[] = [];\n\ttry {\n\t\tfor (const [name, database] of entries) {\n\t\t\tconst wired = checkDatabase(name, database);\n\t\t\tconst { db, connection } = await open(database);\n\t\t\tdatabases.push({\n\t\t\t\tname,\n\t\t\t\tdb,\n\t\t\t\tclient: connection?.client ?? (database.client as never),\n\t\t\t\twired,\n\t\t\t\toptions: (database.options ?? {}) as never,\n\t\t\t\toptionsFor: (database.optionsFor ?? {}) as never,\n\t\t\t\tautoSync: database.autoSync === true,\n\t\t\t\tconnection,\n\t\t\t});\n\t\t\tcheckCollisions(\n\t\t\t\tname,\n\t\t\t\tdb,\n\t\t\t\twired.map(([key]) => key),\n\t\t\t);\n\t\t}\n\t} catch (error) {\n\t\t// Whatever opened before the failure is this call's to give back.\n\t\tfor (const database of databases) await database.connection?.close();\n\t\tthrow error;\n\t}\n\tconst ctx: KitContext = {\n\t\tdatabases,\n\t\tsession: undefined,\n\t\tactor: undefined,\n\t\tcache: new Map(),\n\t\troot: true,\n\t};\n\treturn kitOf<C>(ctx);\n}\n",
9
- "import type { AnyCollectionDefinition, MongoConnection } from '@nxgt/mongo';\nimport type { ClientSession, Db, MongoClient } from 'mongodb';\nimport type { KitCollectionOptions } from '../config/types';\n\n/** A collection as the kit holds it: the key it is reached by, and its definition. */\nexport type Wired = readonly [key: string, definition: AnyCollectionDefinition];\n\n/** One database of a kit, resolved once: data, like `@nxgt/mongo`'s own context. */\nexport interface DatabaseContext {\n\t/** The name the config gave it, which is the key on `kit.databases`. */\n\treadonly name: string;\n\treadonly db: Db;\n\treadonly client: MongoClient;\n\treadonly wired: readonly Wired[];\n\treadonly options: KitCollectionOptions<never>;\n\treadonly optionsFor: Readonly<Record<string, KitCollectionOptions<never>>>;\n\treadonly autoSync: boolean;\n\t/**\n\t * The connection the kit opened, or `undefined` when the config gave a\n\t * client: what it did not open is not its to close.\n\t */\n\treadonly connection: MongoConnection | undefined;\n}\n\n/** What one kit works from. A derived kit shares the databases, not the cache. */\nexport interface KitContext {\n\treadonly databases: readonly DatabaseContext[];\n\treadonly session: ClientSession | undefined;\n\treadonly actor: unknown;\n\t/** The collections already built, per database name then per key. */\n\treadonly cache: Map<string, Map<string, unknown>>;\n\t/** Whether this is the kit `createKit` returned, the only one to close. */\n\treadonly root: boolean;\n}\n\n/** The same kit over another session or actor: a fresh cache, the same databases. */\nexport function derived(\n\tctx: KitContext,\n\tchange: { session?: ClientSession | undefined; actor?: unknown },\n): KitContext {\n\treturn {\n\t\tdatabases: ctx.databases,\n\t\tsession: 'session' in change ? change.session : ctx.session,\n\t\tactor: 'actor' in change ? change.actor : ctx.actor,\n\t\tcache: new Map(),\n\t\troot: false,\n\t};\n}\n\n/** The database under this name, or the one there is. */\nexport function databaseOf(ctx: KitContext, name: string): DatabaseContext {\n\tconst found = ctx.databases.find((database) => database.name === name);\n\tif (!found) {\n\t\tthrow new TypeError(\n\t\t\t`This kit has no database \"${name}\": it has ${ctx.databases\n\t\t\t\t.map((database) => `\"${database.name}\"`)\n\t\t\t\t.join(', ')}.`,\n\t\t);\n\t}\n\treturn found;\n}\n",
5
+ "/** What the kit refused, as a string a caller can switch on. */\nexport type KitErrorCode =\n\t/** The configuration object itself is wrong, and nothing connected. */\n\t| 'CONFIG'\n\t/** A collection is wired under a name that is a member of the driver's `Db`. */\n\t| 'COLLISION'\n\t/** A database was read by a name this kit does not hold. */\n\t| 'NO_DATABASE'\n\t/** `kit.db` was read on a kit that holds more than one database. */\n\t| 'SEVERAL_DATABASES'\n\t/** A transaction that cannot be opened: no client named, or already in one. */\n\t| 'TRANSACTION'\n\t/** `close()` on a kit that `as`, `withSession` or a transaction derived. */\n\t| 'DERIVED'\n\t/** `discoverCollections` could not make a set of definitions from a glob. */\n\t| 'DISCOVERY';\n\nexport interface KitErrorOptions {\n\t/** The database it is about, when one is named. */\n\tdatabase?: string | undefined;\n\t/** The config key, the collection key or the path it is about. */\n\tkey?: string | undefined;\n\tcause?: unknown;\n}\n\n/**\n * What this package refuses, with a code beside the sentence.\n *\n * It extends `TypeError` rather than `Error`, unlike `DataError`,\n * `RedisError` and `S3Error`: every one of these is a call or a\n * configuration written wrong, which is what `TypeError` means, and this\n * package threw bare `TypeError`s before it existed. Extending one keeps\n * every `catch` that tests for `TypeError` working, and adds a `code` to\n * switch on instead of matching the message text.\n */\nexport class KitError extends TypeError {\n\toverride name = 'KitError';\n\treadonly code: KitErrorCode;\n\treadonly database: string | undefined;\n\treadonly key: string | undefined;\n\n\tconstructor(code: KitErrorCode, message: string, options?: KitErrorOptions) {\n\t\tsuper(message, { cause: options?.cause });\n\t\tthis.code = code;\n\t\tthis.database = options?.database;\n\t\tthis.key = options?.key;\n\t}\n}\n",
6
+ "import type { AnyCollectionDefinition } from '@nxgt/mongo';\nimport { KitError } from '../errors/kit-error';\nimport type { DatabaseConfig } from './types';\n\n/** A definition, told by its shape: `instanceof` has no class to ask. */\nexport function isDefinition(value: unknown): value is AnyCollectionDefinition {\n\tif (typeof value !== 'object' || value === null) return false;\n\tconst candidate = value as Partial<AnyCollectionDefinition>;\n\treturn (\n\t\ttypeof candidate.name === 'string' &&\n\t\ttypeof candidate.schema === 'object' &&\n\t\tcandidate.schema !== null &&\n\t\tArray.isArray(candidate.indexes) &&\n\t\ttypeof candidate.stamps === 'object'\n\t);\n}\n\n/** The definitions of a module object, under the keys they are exported by. */\nexport function definitionsOf(\n\tcollections: object,\n): [string, AnyCollectionDefinition][] {\n\treturn Object.entries(collections).filter(\n\t\t(entry): entry is [string, AnyCollectionDefinition] =>\n\t\t\tisDefinition(entry[1]),\n\t);\n}\n\nconst refuse = (name: string, said: string, key?: string): never => {\n\tthrow new KitError('CONFIG', `defineConfig: database \"${name}\" ${said}`, {\n\t\tdatabase: name,\n\t\tkey,\n\t});\n};\n\n/**\n * The collection options the kit decides itself: the database each collection\n * is on, the session and the actor a derived kit carries, and the sync the\n * database's `autoSync` asks for. The types refuse them in `options`, where\n * the shape is `KitCollectionOptions`; under `optionsFor` they are only\n * refused here, and one of them there would quietly outrank the kit.\n */\nconst OWNED = ['db', 'session', 'actor', 'autoSync'] as const;\n\nfunction checkOwned(\n\tname: string,\n\twhat: string,\n\toptions: unknown,\n\tforKey?: string,\n): void {\n\tif (typeof options !== 'object' || options === null) return;\n\tfor (const key of OWNED) {\n\t\tif (key in options) {\n\t\t\trefuse(\n\t\t\t\tname,\n\t\t\t\t`has \"${key}\" in ${what}, which the kit decides: ` +\n\t\t\t\t\t'a database is named by its key, `as` and `withSession` carry the ' +\n\t\t\t\t\t\"actor and the session, and `autoSync` is the database's\",\n\t\t\t\tforKey,\n\t\t\t);\n\t\t}\n\t}\n}\n\n/** Everything one database's config must answer before anything connects. */\nexport function checkDatabase(\n\tname: string,\n\tconfig: DatabaseConfig<object>,\n): [string, AnyCollectionDefinition][] {\n\tif (typeof config !== 'object' || config === null) {\n\t\trefuse(name, 'is not a configuration object');\n\t}\n\tconst hasUri = config.uri !== undefined;\n\tconst hasClient = config.client !== undefined;\n\tif (hasUri === hasClient) {\n\t\trefuse(\n\t\t\tname,\n\t\t\thasUri\n\t\t\t\t? 'has both a uri and a client: pass the one it should use'\n\t\t\t\t: 'has neither a uri nor a client',\n\t\t);\n\t}\n\tif (hasUri && (typeof config.uri !== 'string' || config.uri === '')) {\n\t\trefuse(name, 'has a uri that is not a string');\n\t}\n\tif (hasClient && typeof config.client?.db !== 'function') {\n\t\trefuse(name, 'has a client that is not a MongoClient');\n\t}\n\tif (hasClient && config.clientOptions !== undefined) {\n\t\trefuse(\n\t\t\tname,\n\t\t\t'has client options beside a client it did not open: pass them where the client is made',\n\t\t);\n\t}\n\tif (config.database !== undefined && config.database === '') {\n\t\trefuse(name, 'has an empty database name');\n\t}\n\tif (typeof config.collections !== 'object' || config.collections === null) {\n\t\trefuse(name, 'has no collections object');\n\t}\n\tconst definitions = definitionsOf(config.collections);\n\tif (definitions.length === 0) {\n\t\trefuse(\n\t\t\tname,\n\t\t\t'has a collections object with no definition in it: pass the module, as in `import * as collections`',\n\t\t);\n\t}\n\tconst byName = new Map<string, string>();\n\tfor (const [key, definition] of definitions) {\n\t\tconst seen = byName.get(definition.name);\n\t\tif (seen !== undefined) {\n\t\t\trefuse(\n\t\t\t\tname,\n\t\t\t\t`wires \"${seen}\" and \"${key}\" to the same collection, \"${definition.name}\"`,\n\t\t\t);\n\t\t}\n\t\tbyName.set(definition.name, key);\n\t}\n\tconst keys = new Set(definitions.map(([key]) => key));\n\tfor (const key of Object.keys(config.optionsFor ?? {})) {\n\t\tif (!keys.has(key)) {\n\t\t\trefuse(name, `has options for \"${key}\", which it does not wire`, key);\n\t\t}\n\t}\n\tcheckOwned(name, 'options', config.options);\n\tfor (const [key, options] of Object.entries(config.optionsFor ?? {})) {\n\t\tcheckOwned(name, `the options of \"${key}\"`, options, key);\n\t}\n\treturn definitions;\n}\n",
7
+ "import { KitError } from '../errors/kit-error';\nimport { checkDatabase } from './checks';\nimport type {\n\tChecked,\n\tDatabaseConfig,\n\tKitConfig,\n\tKitConfigInput,\n} from './types';\n\n/** Whether the config named its databases, or is one database itself. */\nfunction databasesOf(\n\tconfig: KitConfigInput,\n): Record<string, DatabaseConfig<object>> {\n\tif (typeof config !== 'object' || config === null) {\n\t\tthrow new KitError(\n\t\t\t'CONFIG',\n\t\t\t'defineConfig: a configuration object is required',\n\t\t);\n\t}\n\tif (!('databases' in config)) {\n\t\treturn { default: config as DatabaseConfig<object> };\n\t}\n\tconst { databases } = config;\n\tif (typeof databases !== 'object' || databases === null) {\n\t\tthrow new KitError(\n\t\t\t'CONFIG',\n\t\t\t'defineConfig: databases must be an object of databases by name, ' +\n\t\t\t\t'as `{ databases: { main: } }`. One database is the ' +\n\t\t\t\t'configuration itself, and names itself with `database`.',\n\t\t);\n\t}\n\tconst names = Object.keys(databases);\n\tif (names.length === 0) {\n\t\tthrow new KitError(\n\t\t\t'CONFIG',\n\t\t\t'defineConfig: databases names none. Give it at least one, ' +\n\t\t\t\t'as `{ databases: { main: } }`.',\n\t\t);\n\t}\n\treturn databases as Record<string, DatabaseConfig<object>>;\n}\n\n/**\n * The configuration of an application's MongoDB, checked once and frozen.\n *\n * ```ts\n * import * as collections from './models';\n *\n * export const config = defineConfig({\n * \turi: process.env.MONGO_URI!,\n * \tcollections,\n * });\n * ```\n *\n * Several databases name themselves:\n *\n * ```ts\n * defineConfig({\n * \tdatabases: {\n * \t\tmain: { uri: process.env.MONGO_URI!, collections },\n * \t\tanalytics: { uri: process.env.ANALYTICS_URI!, collections: events },\n * \t},\n * });\n * ```\n *\n * It connects to nothing and reads no environment variable: what is wrong\n * with the configuration throws here, where the application starts, and the\n * variables are the application's to read.\n */\nexport function defineConfig<const C extends KitConfigInput>(\n\tconfig: C & Checked<C>,\n): KitConfig<C> {\n\tconst databases = databasesOf(config);\n\tfor (const [name, database] of Object.entries(databases)) {\n\t\tcheckDatabase(name, database);\n\t}\n\treturn Object.freeze({\n\t\tdatabases: Object.freeze({ ...databases }),\n\t}) as KitConfig<C>;\n}\n",
8
+ "import type { AnyCollectionDefinition } from '@nxgt/mongo';\nimport { definitionsOf, isDefinition } from './config/checks';\nimport { KitError } from './errors/kit-error';\n\n/** What to scan, and what to read in each file it finds. */\nexport interface DiscoverOptions {\n\t/** A glob, relative to `cwd`: `'src/models/*.model.ts'`. */\n\tglob: string;\n\t/** Where the glob starts. Default: the process's working directory. */\n\tcwd?: string;\n\t/**\n\t * The export to read in each file. Default: every export that is a\n\t * definition, which is what `import * as collections` gives.\n\t */\n\texport?: string;\n}\n\n/**\n * The definitions of the files a glob matches, read at run time.\n *\n * For scripts a sync or a migration run from the repository — and for\n * nothing else: a glob is read from the file system, so it finds nothing\n * once the application is bundled, and it produces **no types**. An\n * application wires its collections with `import * as collections from\n * './models'`, which a bundler follows and the compiler sees.\n *\n * ```ts\n * import { connectMongo, syncCollections } from '@nxgt/mongo';\n * import { discoverCollections } from '@nxgt/mongo-kit';\n *\n * const mongo = await connectMongo(process.env.MONGO_URI!);\n * const definitions = await discoverCollections({ glob: 'src/**\\/*.model.ts' });\n * await syncCollections(mongo.db, definitions);\n * await mongo.close();\n * ```\n *\n * The files are imported, so their top level runs, and the glob is\n * `Bun.Glob`: this one function needs the Bun runtime.\n */\nexport async function discoverCollections(\n\toptions: DiscoverOptions,\n): Promise<AnyCollectionDefinition[]> {\n\tconst { glob, cwd = process.cwd(), export: name } = options;\n\tif (typeof glob !== 'string' || glob === '') {\n\t\tthrow new KitError('DISCOVERY', 'discoverCollections: a glob is required');\n\t}\n\tconst paths = await Array.fromAsync(new Bun.Glob(glob).scan({ cwd }));\n\tconst found: AnyCollectionDefinition[] = [];\n\tconst byName = new Map<string, string>();\n\tfor (const path of paths.sort()) {\n\t\tconst module = (await import(`${cwd}/${path}`)) as Record<string, unknown>;\n\t\tconst definitions =\n\t\t\tname === undefined\n\t\t\t\t? definitionsOf(module)\n\t\t\t\t: isDefinition(module[name])\n\t\t\t\t\t? ([[name, module[name]]] as [string, AnyCollectionDefinition][])\n\t\t\t\t\t: [];\n\t\tif (name !== undefined && definitions.length === 0) {\n\t\t\tthrow new KitError(\n\t\t\t\t'DISCOVERY',\n\t\t\t\t`discoverCollections: ${path} exports no definition named \"${name}\"`,\n\t\t\t\t{ key: path },\n\t\t\t);\n\t\t}\n\t\tfor (const [, definition] of definitions) {\n\t\t\tconst seen = byName.get(definition.name);\n\t\t\tif (seen !== undefined && seen !== path) {\n\t\t\t\tthrow new KitError(\n\t\t\t\t\t'DISCOVERY',\n\t\t\t\t\t`discoverCollections: ${seen} and ${path} both define the collection \"${definition.name}\"`,\n\t\t\t\t\t{ key: path },\n\t\t\t\t);\n\t\t\t}\n\t\t\tbyName.set(definition.name, path);\n\t\t\tfound.push(definition);\n\t\t}\n\t}\n\treturn found;\n}\n",
9
+ "import { connectMongo, type MongoConnection } from '@nxgt/mongo';\nimport type { Db } from 'mongodb';\nimport { checkDatabase } from '../config/checks';\nimport type { DatabaseConfig, KitConfig } from '../config/types';\nimport { KitError } from '../errors/kit-error';\nimport type { DatabaseContext, KitContext } from './context';\nimport { kitOf } from './derive';\nimport type { MongoKit } from './types';\n\n/** Where one database is, and whether the kit opened it itself. */\nasync function open(\n\tconfig: DatabaseConfig<object>,\n): Promise<{ db: Db; connection: MongoConnection | undefined }> {\n\tif (config.client) {\n\t\tconst client = config.client;\n\t\treturn {\n\t\t\tdb: config.database ? client.db(config.database) : client.db(),\n\t\t\tconnection: undefined,\n\t\t};\n\t}\n\tconst connection = await connectMongo(\n\t\tconfig.uri as string,\n\t\tconfig.clientOptions,\n\t);\n\treturn {\n\t\tdb: config.database ? connection.client.db(config.database) : connection.db,\n\t\tconnection,\n\t};\n}\n\n/**\n * A key the driver's `Db` already answers to would be unreachable on the\n * scope. The types refuse it where the config is written; this asks the\n * object itself, so a member the driver adds in a later release is caught\n * here rather than silently shadowed.\n */\nfunction checkCollisions(name: string, db: Db, keys: readonly string[]): void {\n\tfor (const key of keys) {\n\t\tif (key in db) {\n\t\t\tthrow new KitError(\n\t\t\t\t'COLLISION',\n\t\t\t\t`createKit: database \"${name}\" wires a collection under \"${key}\", ` +\n\t\t\t\t\t\"which is a member of the driver's Db: it would be unreachable. \" +\n\t\t\t\t\t'Export that definition under another name.',\n\t\t\t\t{ database: name, key },\n\t\t\t);\n\t\t}\n\t}\n}\n\n/**\n * Opens what the configuration describes, and gives the application its\n * collections on their database.\n *\n * ```ts\n * await using kit = await createKit(config);\n * const user = await kit.db.users.create({ email: 'ada@example.com' });\n * ```\n *\n * A database with a `uri` takes a hold on the client `connectMongo` shares\n * for that URI, and `close()` gives it back; a database given a `client` uses\n * it and never closes it. Nothing is built ahead of the connections: a\n * collection is built the first time it is read.\n */\nexport async function createKit<C>(config: KitConfig<C>): Promise<MongoKit<C>> {\n\tconst entries = Object.entries(config.databases) as [\n\t\tstring,\n\t\tDatabaseConfig<object>,\n\t][];\n\tconst databases: DatabaseContext[] = [];\n\ttry {\n\t\tfor (const [name, database] of entries) {\n\t\t\tconst wired = checkDatabase(name, database);\n\t\t\tconst { db, connection } = await open(database);\n\t\t\tdatabases.push({\n\t\t\t\tname,\n\t\t\t\tdb,\n\t\t\t\tclient: connection?.client ?? (database.client as never),\n\t\t\t\twired,\n\t\t\t\toptions: (database.options ?? {}) as never,\n\t\t\t\toptionsFor: (database.optionsFor ?? {}) as never,\n\t\t\t\tautoSync: database.autoSync === true,\n\t\t\t\tconnection,\n\t\t\t});\n\t\t\tcheckCollisions(\n\t\t\t\tname,\n\t\t\t\tdb,\n\t\t\t\twired.map(([key]) => key),\n\t\t\t);\n\t\t}\n\t} catch (error) {\n\t\t// Whatever opened before the failure is this call's to give back.\n\t\tfor (const database of databases) await database.connection?.close();\n\t\tthrow error;\n\t}\n\tconst ctx: KitContext = {\n\t\tdatabases,\n\t\tsession: undefined,\n\t\tactor: undefined,\n\t\tcache: new Map(),\n\t\troot: true,\n\t};\n\treturn kitOf<C>(ctx);\n}\n",
10
+ "import type { AnyCollectionDefinition, MongoConnection } from '@nxgt/mongo';\nimport type { ClientSession, Db, MongoClient } from 'mongodb';\nimport type { KitCollectionOptions } from '../config/types';\nimport { KitError } from '../errors/kit-error';\n\n/** A collection as the kit holds it: the key it is reached by, and its definition. */\nexport type Wired = readonly [key: string, definition: AnyCollectionDefinition];\n\n/** One database of a kit, resolved once: data, like `@nxgt/mongo`'s own context. */\nexport interface DatabaseContext {\n\t/** The name the config gave it, which is the key on `kit.databases`. */\n\treadonly name: string;\n\treadonly db: Db;\n\treadonly client: MongoClient;\n\treadonly wired: readonly Wired[];\n\treadonly options: KitCollectionOptions<never>;\n\treadonly optionsFor: Readonly<Record<string, KitCollectionOptions<never>>>;\n\treadonly autoSync: boolean;\n\t/**\n\t * The connection the kit opened, or `undefined` when the config gave a\n\t * client: what it did not open is not its to close.\n\t */\n\treadonly connection: MongoConnection | undefined;\n}\n\n/** What one kit works from. A derived kit shares the databases, not the cache. */\nexport interface KitContext {\n\treadonly databases: readonly DatabaseContext[];\n\treadonly session: ClientSession | undefined;\n\treadonly actor: unknown;\n\t/** The collections already built, per database name then per key. */\n\treadonly cache: Map<string, Map<string, unknown>>;\n\t/** Whether this is the kit `createKit` returned, the only one to close. */\n\treadonly root: boolean;\n}\n\n/** The same kit over another session or actor: a fresh cache, the same databases. */\nexport function derived(\n\tctx: KitContext,\n\tchange: { session?: ClientSession | undefined; actor?: unknown },\n): KitContext {\n\treturn {\n\t\tdatabases: ctx.databases,\n\t\tsession: 'session' in change ? change.session : ctx.session,\n\t\tactor: 'actor' in change ? change.actor : ctx.actor,\n\t\tcache: new Map(),\n\t\troot: false,\n\t};\n}\n\n/** The database under this name, or the one there is. */\nexport function databaseOf(ctx: KitContext, name: string): DatabaseContext {\n\tconst found = ctx.databases.find((database) => database.name === name);\n\tif (!found) {\n\t\tthrow new KitError(\n\t\t\t'NO_DATABASE',\n\t\t\t`This kit has no database \"${name}\": it has ${ctx.databases\n\t\t\t\t.map((database) => `\"${database.name}\"`)\n\t\t\t\t.join(', ')}.`,\n\t\t\t{ database: name },\n\t\t);\n\t}\n\treturn found;\n}\n",
10
11
  "import { getCollection } from '@nxgt/mongo';\nimport type { DatabaseContext, KitContext } from './context';\n\n/**\n * The collection under `key`, built the first time it is read and kept:\n * `getCollection` caches nothing, so a scope that built them all would pay\n * for every collection on every request that derives a kit.\n */\nexport function collectionAt(\n\tctx: KitContext,\n\tdatabase: DatabaseContext,\n\tkey: string,\n\tdefinition: DatabaseContext['wired'][number][1],\n): unknown {\n\tlet built = ctx.cache.get(database.name);\n\tif (!built) {\n\t\tbuilt = new Map();\n\t\tctx.cache.set(database.name, built);\n\t}\n\tconst found = built.get(key);\n\tif (found) return found;\n\tconst collection = getCollection(database.db, definition, {\n\t\t...database.options,\n\t\t...database.optionsFor[key],\n\t\t...(database.autoSync ? { autoSync: true } : {}),\n\t\t...(ctx.session ? { session: ctx.session } : {}),\n\t\t...(ctx.actor === undefined ? {} : { actor: ctx.actor }),\n\t} as never);\n\tbuilt.set(key, collection);\n\treturn collection;\n}\n\n/**\n * A database with its collections on it. The collections are own properties,\n * so `Object.keys` lists them; everything else is the driver's `Db`, read\n * through a proxy — the shape `getCollection` already uses to put this\n * package's methods over the driver's collection.\n *\n * A key the `Db` already answers to never reaches here: `createKit` refuses\n * it, and the types refuse it before that.\n */\nexport function scopeOf(ctx: KitContext, database: DatabaseContext): object {\n\tconst collections: Record<string, unknown> = {};\n\tfor (const [key, definition] of database.wired) {\n\t\tObject.defineProperty(collections, key, {\n\t\t\tenumerable: true,\n\t\t\tget: () => collectionAt(ctx, database, key, definition),\n\t\t});\n\t}\n\treturn new Proxy(collections, {\n\t\tget(target, key, receiver) {\n\t\t\tif (Reflect.has(target, key)) return Reflect.get(target, key, receiver);\n\t\t\tconst value = Reflect.get(database.db, key) as unknown;\n\t\t\treturn typeof value === 'function' ? value.bind(database.db) : value;\n\t\t},\n\t\thas(target, key) {\n\t\t\treturn Reflect.has(target, key) || Reflect.has(database.db, key);\n\t\t},\n\t});\n}\n",
11
12
  "import {\n\ttype SyncOptions,\n\ttype SyncReport,\n\tsyncCollections,\n} from '@nxgt/mongo';\nimport type { KitContext } from './context';\n\n/**\n * Syncs exactly the collections the kit wires, database by database — which\n * `syncAll` cannot do, since the registry knows no database.\n *\n * A deployment step: `collMod` needs the `dbAdmin` role, and neither it nor\n * an index build runs in a transaction. The first database that throws stops\n * the rest, so a `dryRun` is the way to see everything at once.\n */\nexport async function syncKit(\n\tctx: KitContext,\n\toptions: SyncOptions = {},\n): Promise<Record<string, SyncReport[]>> {\n\tconst reports: Record<string, SyncReport[]> = {};\n\tfor (const database of ctx.databases) {\n\t\treports[database.name] = await syncCollections(\n\t\t\tdatabase.db,\n\t\t\tdatabase.wired.map(([, definition]) => definition),\n\t\t\toptions,\n\t\t);\n\t}\n\treturn reports;\n}\n",
12
- "import { type TransactionHost, withTransaction } from '@nxgt/mongo';\nimport type { MongoClient, TransactionOptions } from 'mongodb';\nimport { databaseOf, derived, type KitContext } from './context';\n\n/**\n * The client a transaction runs on. One transaction lives on one client, so\n * a kit holding several has to be told which — there is no transaction\n * across clients to give.\n */\nexport function clientFor(\n\tctx: KitContext,\n\ton: string | undefined,\n): MongoClient {\n\tif (on !== undefined) return databaseOf(ctx, on).client;\n\tconst clients = new Set(ctx.databases.map((database) => database.client));\n\tconst [only] = clients;\n\tif (clients.size === 1 && only) return only;\n\tthrow new TypeError(\n\t\t'transaction: this kit holds more than one client, and a transaction ' +\n\t\t\t\"lives on one. Name the database it runs on, as `{ on: 'main' }`.\",\n\t);\n}\n\n/**\n * What the transaction runs on: the kit's own session when it has one, so\n * that a transaction inside a transaction **joins** the outer one rather than\n * opening a second, independent one beside it; a client otherwise.\n */\nexport function hostFor(\n\tctx: KitContext,\n\ton: string | undefined,\n): TransactionHost {\n\tif (!ctx.session) return clientFor(ctx, on);\n\tif (on !== undefined) {\n\t\tthrow new TypeError(\n\t\t\t'transaction: this kit is already in a session, which this call ' +\n\t\t\t\t'joins, so `on` has no client left to choose.',\n\t\t);\n\t}\n\treturn ctx.session;\n}\n\n/**\n * Runs `fn` in a transaction, with a kit whose collections are all in it.\n * The driver retries `fn` from the start on a transient error, so `fn` must\n * be safe to run twice — `@nxgt/mongo`'s `withTransaction` says the rest.\n */\nexport async function transact<T>(\n\tctx: KitContext,\n\tbuild: (ctx: KitContext) => unknown,\n\tfn: (kit: never) => Promise<T>,\n\toptions: (TransactionOptions & { on?: string }) | undefined,\n): Promise<T> {\n\tconst { on, ...rest } = options ?? {};\n\tconst host = hostFor(ctx, on);\n\tconst transactionOptions =\n\t\tObject.keys(rest).length > 0 ? (rest as TransactionOptions) : undefined;\n\treturn withTransaction(\n\t\thost,\n\t\t(session) => fn(build(derived(ctx, { session })) as never),\n\t\ttransactionOptions,\n\t);\n}\n",
13
- "import type { SyncOptions } from '@nxgt/mongo';\nimport { databaseOf, derived, type KitContext } from './context';\nimport { scopeOf } from './scope';\nimport { syncKit } from './sync';\nimport { transact } from './transaction';\nimport type { KitTransactionOptions, MongoKit } from './types';\n\n/**\n * Closes what this kit's context opened. Idempotent, because each\n * `MongoConnection` is: a second call awaits the first one's work.\n */\nasync function closeKit(ctx: KitContext): Promise<void> {\n\tif (!ctx.root) {\n\t\tthrow new TypeError(\n\t\t\t'close: this kit came from `as`, `withSession` or a transaction. ' +\n\t\t\t\t'Close the kit `createKit` returned — the clients are shared.',\n\t\t);\n\t}\n\tfor (const database of ctx.databases) {\n\t\tawait database.connection?.close();\n\t}\n}\n\n/**\n * A kit over one context. `as` and `withSession` build another over a new\n * context, sharing the databases and the clients: only the collections are\n * built again, and only the ones a caller reads.\n */\nexport function kitOf<C>(ctx: KitContext): MongoKit<C> {\n\tconst scopes = new Map<string, object>();\n\tconst scopeFor = (name: string): object => {\n\t\tconst found = scopes.get(name);\n\t\tif (found) return found;\n\t\tconst scope = scopeOf(ctx, databaseOf(ctx, name));\n\t\tscopes.set(name, scope);\n\t\treturn scope;\n\t};\n\n\tconst databases = {} as Record<string, object>;\n\tconst clients = {} as Record<string, unknown>;\n\tfor (const database of ctx.databases) {\n\t\tObject.defineProperty(databases, database.name, {\n\t\t\tenumerable: true,\n\t\t\tget: () => scopeFor(database.name),\n\t\t});\n\t\tObject.defineProperty(clients, database.name, {\n\t\t\tenumerable: true,\n\t\t\tvalue: database.client,\n\t\t});\n\t}\n\n\tconst kit: MongoKit<C> = {\n\t\tget db() {\n\t\t\tconst [only] = ctx.databases;\n\t\t\tif (ctx.databases.length !== 1 || !only) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t'kit.db: this kit has several databases. Read the one you mean, ' +\n\t\t\t\t\t\t`as \\`kit.databases.${ctx.databases[0]?.name ?? 'main'}\\`.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn scopeFor(only.name) as never;\n\t\t},\n\t\tdatabases: databases as never,\n\t\tclients: clients as never,\n\t\tget actor() {\n\t\t\treturn ctx.actor as never;\n\t\t},\n\t\tget session() {\n\t\t\treturn ctx.session;\n\t\t},\n\t\tas(actor) {\n\t\t\treturn kitOf<C>(derived(ctx, { actor }));\n\t\t},\n\t\twithSession(session) {\n\t\t\treturn kitOf<C>(derived(ctx, { session }));\n\t\t},\n\t\ttransaction<T>(\n\t\t\tfn: (kit: MongoKit<C>) => Promise<T>,\n\t\t\toptions?: KitTransactionOptions<C>,\n\t\t): Promise<T> {\n\t\t\treturn transact(\n\t\t\t\tctx,\n\t\t\t\t(next) => kitOf<C>(next),\n\t\t\t\tfn as never,\n\t\t\t\toptions as never,\n\t\t\t);\n\t\t},\n\t\tsync(options?: SyncOptions) {\n\t\t\treturn syncKit(ctx, options) as never;\n\t\t},\n\t\tclose() {\n\t\t\treturn closeKit(ctx);\n\t\t},\n\t\t[Symbol.asyncDispose]() {\n\t\t\treturn closeKit(ctx);\n\t\t},\n\t};\n\treturn kit;\n}\n"
13
+ "import { type TransactionHost, withTransaction } from '@nxgt/mongo';\nimport type { MongoClient, TransactionOptions } from 'mongodb';\nimport { KitError } from '../errors/kit-error';\nimport { databaseOf, derived, type KitContext } from './context';\n\n/**\n * The client a transaction runs on. One transaction lives on one client, so\n * a kit holding several has to be told which — there is no transaction\n * across clients to give.\n */\nexport function clientFor(\n\tctx: KitContext,\n\ton: string | undefined,\n): MongoClient {\n\tif (on !== undefined) return databaseOf(ctx, on).client;\n\tconst clients = new Set(ctx.databases.map((database) => database.client));\n\tconst [only] = clients;\n\tif (clients.size === 1 && only) return only;\n\tthrow new KitError(\n\t\t'TRANSACTION',\n\t\t'transaction: this kit holds more than one client, and a transaction ' +\n\t\t\t\"lives on one. Name the database it runs on, as `{ on: 'main' }`.\",\n\t);\n}\n\n/**\n * What the transaction runs on: the kit's own session when it has one, so\n * that a transaction inside a transaction **joins** the outer one rather than\n * opening a second, independent one beside it; a client otherwise.\n */\nexport function hostFor(\n\tctx: KitContext,\n\ton: string | undefined,\n): TransactionHost {\n\tif (!ctx.session) return clientFor(ctx, on);\n\tif (on !== undefined) {\n\t\tthrow new KitError(\n\t\t\t'TRANSACTION',\n\t\t\t'transaction: this kit is already in a session, which this call ' +\n\t\t\t\t'joins, so `on` has no client left to choose.',\n\t\t);\n\t}\n\treturn ctx.session;\n}\n\n/**\n * Runs `fn` in a transaction, with a kit whose collections are all in it.\n * The driver retries `fn` from the start on a transient error, so `fn` must\n * be safe to run twice — `@nxgt/mongo`'s `withTransaction` says the rest.\n */\nexport async function transact<T>(\n\tctx: KitContext,\n\tbuild: (ctx: KitContext) => unknown,\n\tfn: (kit: never) => Promise<T>,\n\toptions: (TransactionOptions & { on?: string }) | undefined,\n): Promise<T> {\n\tconst { on, ...rest } = options ?? {};\n\tconst host = hostFor(ctx, on);\n\tconst transactionOptions =\n\t\tObject.keys(rest).length > 0 ? (rest as TransactionOptions) : undefined;\n\treturn withTransaction(\n\t\thost,\n\t\t(session) => fn(build(derived(ctx, { session })) as never),\n\t\ttransactionOptions,\n\t);\n}\n",
14
+ "import type { SyncOptions } from '@nxgt/mongo';\nimport { KitError } from '../errors/kit-error';\nimport { databaseOf, derived, type KitContext } from './context';\nimport { scopeOf } from './scope';\nimport { syncKit } from './sync';\nimport { transact } from './transaction';\nimport type { KitTransactionOptions, MongoKit } from './types';\n\n/**\n * Closes what this kit's context opened. Idempotent, because each\n * `MongoConnection` is: a second call awaits the first one's work.\n */\nasync function closeKit(ctx: KitContext): Promise<void> {\n\tif (!ctx.root) {\n\t\tthrow new KitError(\n\t\t\t'DERIVED',\n\t\t\t'close: this kit came from `as`, `withSession` or a transaction. ' +\n\t\t\t\t'Close the kit `createKit` returned — the clients are shared.',\n\t\t);\n\t}\n\tfor (const database of ctx.databases) {\n\t\tawait database.connection?.close();\n\t}\n}\n\n/**\n * A kit over one context. `as` and `withSession` build another over a new\n * context, sharing the databases and the clients: only the collections are\n * built again, and only the ones a caller reads.\n */\nexport function kitOf<C>(ctx: KitContext): MongoKit<C> {\n\tconst scopes = new Map<string, object>();\n\tconst scopeFor = (name: string): object => {\n\t\tconst found = scopes.get(name);\n\t\tif (found) return found;\n\t\tconst scope = scopeOf(ctx, databaseOf(ctx, name));\n\t\tscopes.set(name, scope);\n\t\treturn scope;\n\t};\n\n\tconst databases = {} as Record<string, object>;\n\tconst clients = {} as Record<string, unknown>;\n\tfor (const database of ctx.databases) {\n\t\tObject.defineProperty(databases, database.name, {\n\t\t\tenumerable: true,\n\t\t\tget: () => scopeFor(database.name),\n\t\t});\n\t\tObject.defineProperty(clients, database.name, {\n\t\t\tenumerable: true,\n\t\t\tvalue: database.client,\n\t\t});\n\t}\n\n\tconst kit: MongoKit<C> = {\n\t\tget db() {\n\t\t\tconst [only] = ctx.databases;\n\t\t\tif (ctx.databases.length !== 1 || !only) {\n\t\t\t\tthrow new KitError(\n\t\t\t\t\t'SEVERAL_DATABASES',\n\t\t\t\t\t'kit.db: this kit has several databases. Read the one you mean, ' +\n\t\t\t\t\t\t`as \\`kit.databases.${ctx.databases[0]?.name ?? 'main'}\\`.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn scopeFor(only.name) as never;\n\t\t},\n\t\tdatabases: databases as never,\n\t\tclients: clients as never,\n\t\tget actor() {\n\t\t\treturn ctx.actor as never;\n\t\t},\n\t\tget session() {\n\t\t\treturn ctx.session;\n\t\t},\n\t\tas(actor) {\n\t\t\treturn kitOf<C>(derived(ctx, { actor }));\n\t\t},\n\t\twithSession(session) {\n\t\t\treturn kitOf<C>(derived(ctx, { session }));\n\t\t},\n\t\ttransaction<T>(\n\t\t\tfn: (kit: MongoKit<C>) => Promise<T>,\n\t\t\toptions?: KitTransactionOptions<C>,\n\t\t): Promise<T> {\n\t\t\treturn transact(\n\t\t\t\tctx,\n\t\t\t\t(next) => kitOf<C>(next),\n\t\t\t\tfn as never,\n\t\t\t\toptions as never,\n\t\t\t);\n\t\t},\n\t\tsync(options?: SyncOptions) {\n\t\t\treturn syncKit(ctx, options) as never;\n\t\t},\n\t\tclose() {\n\t\t\treturn closeKit(ctx);\n\t\t},\n\t\t[Symbol.asyncDispose]() {\n\t\t\treturn closeKit(ctx);\n\t\t},\n\t};\n\treturn kit;\n}\n"
14
15
  ],
15
- "mappings": "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",
16
- "debugId": "00B9BBA5C20F9E8D64756E2164756E21",
16
+ "mappings": "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",
17
+ "debugId": "D45C9A203331820F64756E2164756E21",
17
18
  "names": []
18
19
  }
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/kit/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,sFAAsF;AACtF,MAAM,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,uBAAuB,CAAC,CAAC;AAEhF,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,KAAK,EAAE,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC;CACjD;AAED,kFAAkF;AAClF,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB;AAED,qFAAqF;AACrF,wBAAgB,OAAO,CACtB,GAAG,EAAE,UAAU,EACf,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9D,UAAU,CAQZ;AAED,yDAAyD;AACzD,wBAAgB,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAUzE"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/kit/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAG5D,sFAAsF;AACtF,MAAM,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,uBAAuB,CAAC,CAAC;AAEhF,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC/B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,KAAK,EAAE,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC3E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,UAAU,EAAE,eAAe,GAAG,SAAS,CAAC;CACjD;AAED,kFAAkF;AAClF,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC;IAC5C,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,2EAA2E;IAC3E,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB;AAED,qFAAqF;AACrF,wBAAgB,OAAO,CACtB,GAAG,EAAE,UAAU,EACf,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9D,UAAU,CAQZ;AAED,yDAAyD;AACzD,wBAAgB,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,eAAe,CAYzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"create-kit.d.ts","sourceRoot":"","sources":["../../src/kit/create-kit.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAkB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAyCxC;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAuC7E"}
1
+ {"version":3,"file":"create-kit.d.ts","sourceRoot":"","sources":["../../src/kit/create-kit.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAkB,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AA2CxC;;;;;;;;;;;;;GAaG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAuC7E"}
@@ -1 +1 @@
1
- {"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../src/kit/derive.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,EAAyB,QAAQ,EAAE,MAAM,SAAS,CAAC;AAkB/D;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,CAsErD"}
1
+ {"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../src/kit/derive.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAIjE,OAAO,KAAK,EAAyB,QAAQ,EAAE,MAAM,SAAS,CAAC;AAmB/D;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,CAuErD"}
@@ -1 +1 @@
1
- {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/kit/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAmB,MAAM,aAAa,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAuB,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,SAAS,CACxB,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,MAAM,GAAG,SAAS,GACpB,WAAW,CASb;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACtB,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,MAAM,GAAG,SAAS,GACpB,eAAe,CASjB;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC/B,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACnC,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,OAAO,EAAE,CAAC,kBAAkB,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,GACzD,OAAO,CAAC,CAAC,CAAC,CAUZ"}
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/kit/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAmB,MAAM,aAAa,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE/D,OAAO,EAAuB,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,SAAS,CACxB,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,MAAM,GAAG,SAAS,GACpB,WAAW,CAUb;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CACtB,GAAG,EAAE,UAAU,EACf,EAAE,EAAE,MAAM,GAAG,SAAS,GACpB,eAAe,CAUjB;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAC/B,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,CAAC,GAAG,EAAE,UAAU,KAAK,OAAO,EACnC,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,EAC9B,OAAO,EAAE,CAAC,kBAAkB,GAAG;IAAE,EAAE,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,SAAS,GACzD,OAAO,CAAC,CAAC,CAAC,CAUZ"}
package/docs/README.md ADDED
@@ -0,0 +1,15 @@
1
+ # `@nxgt/mongo-kit` documentation
2
+
3
+ The [README](../README.md) is the short version: what the package is, and one
4
+ example per area. These pages are the long one.
5
+
6
+ | Page | Read it when |
7
+ | --- | --- |
8
+ | [Configuration](guide/configuration.md) | you are describing the databases and the collections of an application, one database or several |
9
+ | [The `db` scope](guide/db-scope.md) | you are reading `kit.db.users`, reaching for something only the driver's `Db` has, or wondering when a collection is built |
10
+ | [The actor, sessions and transactions](guide/actor-and-transactions.md) | a write has to be stamped with who made it, or several writes have to commit together |
11
+ | [Syncing](guide/sync.md) | the collections, their validators and their indexes have to exist on the server |
12
+ | [`discoverCollections`](guide/discover-collections.md) | a script has to find the definitions of a repository without importing each one |
13
+ | [Errors](guide/errors.md) | something was refused — a configuration, a name, a transaction, a close — and you want the code to switch on |
14
+ | [Troubleshooting](troubleshooting.md) | something threw, and you have the message |
15
+ | [Roadmap](roadmap.md) | you want to know what is coming, and what will not |
@@ -0,0 +1,196 @@
1
+ # The actor, sessions and transactions
2
+
3
+ Who a write is stamped as, and which writes commit together. Both are kits of
4
+ their own: `as`, `withSession` and `transaction` give back **another kit**
5
+ over the same clients, and leave the one they came from alone.
6
+
7
+ ```ts
8
+ import { ObjectId } from 'mongodb';
9
+ import { kit } from './db'; // the kit `createKit` returned
10
+
11
+ const actor = new ObjectId();
12
+
13
+ const post = await kit.as(actor).db.posts.create({ title: 'a' });
14
+ post.createdBy; // the actor
15
+
16
+ const plain = await kit.db.posts.create({ title: 'b' });
17
+ plain.createdBy; // null — the kit it came from never changed
18
+ ```
19
+
20
+ ## `as(actor)`
21
+
22
+ One call stamps every collection of the kit: `createdBy` on a create,
23
+ `updatedBy` on an update, `deletedBy` on a soft delete — whichever stamps the
24
+ definition asked for.
25
+
26
+ ```ts
27
+ const writer = kit.as(actor);
28
+ await writer.db.users.create({ email: 'ada@example.com' }); // createdBy
29
+ await writer.db.posts.create({ title: 'a' }); // createdBy
30
+ writer.actor; // the actor
31
+ writer.clients.default === kit.clients.default; // the same client
32
+ writer.db.users !== kit.db.users; // its own collections
33
+ ```
34
+
35
+ The actor's **type** is the one the collections agree on: a kit whose
36
+ collections all stamp an `ObjectId` takes an `ObjectId`. A kit whose
37
+ collections stamp no actor has no `as` to call — its type is `never` — and so
38
+ does one whose collections stamp actors of different types, since a single
39
+ call could not stamp both.
40
+
41
+ ```ts
42
+ type KitActor<C>; // the intersection of every wired definition's ActorOf
43
+ ```
44
+
45
+ ## `withSession(session)`
46
+
47
+ The kit's collections all run in that session; `undefined` takes it away
48
+ again.
49
+
50
+ ```ts
51
+ const session = kit.clients.default.startSession();
52
+ try {
53
+ const inSession = kit.withSession(session);
54
+ await inSession.db.users.create({ email: 'ada@example.com' });
55
+ inSession.withSession(undefined).session; // undefined
56
+ } finally {
57
+ await session.endSession();
58
+ }
59
+ ```
60
+
61
+ `as` and `withSession` compose, in either order, and each keeps what the
62
+ other set.
63
+
64
+ ## `transaction(fn, options?)`
65
+
66
+ The body is given a kit whose collections are **all** in the transaction:
67
+ nothing has to be threaded through.
68
+
69
+ ```ts
70
+ const written = await kit.as(actor).transaction(async (tx) => {
71
+ const team = await tx.db.teams.create({ name: 'Core' });
72
+ await tx.db.users.update(userId, { teamId: team._id });
73
+ return team;
74
+ });
75
+ ```
76
+
77
+ If the body throws, everything it wrote is rolled back and the error comes
78
+ back out:
79
+
80
+ ```ts
81
+ await kit.transaction(async (tx) => {
82
+ await tx.db.users.create({ email: 'ada@example.com' });
83
+ throw new Error('no');
84
+ });
85
+ // rejects with 'no'; the user is not there
86
+ await kit.db.users.count(); // 0
87
+ ```
88
+
89
+ | Option | Type | Default | Effect |
90
+ | --- | --- | --- | --- |
91
+ | `on` | `DbName<C>` | the only client | Which database's client carries the transaction. Required once the kit holds more than one **client** |
92
+ | `readConcern`, `writeConcern`, `readPreference`, `maxCommitTimeMS` | the driver's `TransactionOptions` | the client's | Passed to the driver as they are |
93
+
94
+ ```ts
95
+ await kit.transaction(
96
+ (tx) => tx.db.users.create({ email: 'ada@example.com' }),
97
+ { readConcern: { level: 'snapshot' }, writeConcern: { w: 'majority' } },
98
+ );
99
+ ```
100
+
101
+ ### What the body must accept
102
+
103
+ - **It may run twice.** The driver retries it from the start on a transient
104
+ error, so it must hold nothing MongoDB would not roll back — no email sent,
105
+ no counter raised in Redis, no file written.
106
+ - **A transaction inside a transaction joins the outer one**, and takes no
107
+ `on`: the session has already decided. MongoDB has no savepoints, so an
108
+ inner failure takes the whole transaction with it.
109
+ - **It reaches one client's databases.** With `{ on: 'main' }`, an operation
110
+ on a database of another client carries a session that client does not own,
111
+ and the driver refuses it.
112
+ - **A replica set is required**, which is MongoDB's own rule for
113
+ transactions, not this package's.
114
+
115
+ ```ts
116
+ await kit.transaction(async (outer) => {
117
+ await outer.db.users.create({ email: 'ada@example.com' });
118
+ await outer.transaction(async (inner) => {
119
+ inner.session === outer.session; // true: it joined
120
+ await inner.db.posts.create({ title: 'a' });
121
+ });
122
+ });
123
+ ```
124
+
125
+ `{ on }` is required at **run time**, not by the types, and cannot be: two
126
+ databases on one URI share a client and need none, so what decides is the
127
+ number of clients. A kit holding two without it throws a
128
+ [`KitError`](errors.md) with `code: 'TRANSACTION'`, naming what to write.
129
+
130
+ ## In a request
131
+
132
+ The kit is built once; each request derives the kit that stamps its user, and
133
+ a handler is handed services built on it rather than the kit itself.
134
+
135
+ ```ts
136
+ import { tryObjectId } from '@nxgt/mongo';
137
+ import { createMiddleware } from 'hono/factory';
138
+ import type { Kit } from '../db';
139
+ import { buildServices } from '../context';
140
+
141
+ export const provideServices = (kit: Kit) =>
142
+ createMiddleware(async (c, next) => {
143
+ const actor = tryObjectId(c.req.header('x-user-id'));
144
+ if (!actor) return c.json({ message: 'errors.unauthenticated' }, 401);
145
+ c.set('services', buildServices(kit.as(actor)));
146
+ await next();
147
+ });
148
+ ```
149
+
150
+ ```ts
151
+ export class TeamService {
152
+ constructor(private readonly kit: Kit) {}
153
+
154
+ /** Two collections, one commit — and both writes stamped with the request's user. */
155
+ createWithOwner(name: string, ownerId: ObjectId) {
156
+ return this.kit.transaction(async (tx) => {
157
+ const team = await tx.db.teams.create({ name });
158
+ await tx.db.users.update(ownerId, { teamId: team._id });
159
+ return team;
160
+ });
161
+ }
162
+ }
163
+ ```
164
+
165
+ The service holds the request's kit, so `this.kit.transaction` already stamps
166
+ the right actor: the transaction inherits it.
167
+
168
+ ## Closing a derived kit
169
+
170
+ `close()` on a kit from `as`, `withSession` or a transaction throws — the
171
+ clients belong to the kit `createKit` returned, and that is the one to close.
172
+
173
+ ## Signatures
174
+
175
+ ```ts
176
+ type KitActor<C> = [ActorOf<WiredDefinition<C>>] extends [never]
177
+ ? never
178
+ : UnionToIntersection<ActorOf<WiredDefinition<C>>>;
179
+
180
+ type KitTransactionOptions<C> = TransactionOptions & { on?: DbName<C> };
181
+
182
+ interface MongoKit<C> {
183
+ as(actor: KitActor<C>): MongoKit<C>;
184
+ withSession(session: ClientSession | undefined): MongoKit<C>;
185
+ transaction<T>(
186
+ fn: (kit: MongoKit<C>) => Promise<T>,
187
+ options?: KitTransactionOptions<C>,
188
+ ): Promise<T>;
189
+ }
190
+ ```
191
+
192
+ ## Next
193
+
194
+ - [The `db` scope](db-scope.md) — what a derived kit shares, and what it
195
+ builds again.
196
+ - [Troubleshooting](../troubleshooting.md) — the messages these refusals use.