Download src/lib/mongodb.ts from helo-ayush/NewIntentExtractor: direct link, hf CLI and curl.
- Browser
- Download file 4.18 kB
-
https://huggingface.co/spaces/helo-ayush/NewIntentExtractor/resolve/main/src/lib/mongodb.ts
- Command line
-
hf download hf://spaces/helo-ayush/NewIntentExtractor/src/lib/mongodb.ts
-
curl -L -o mongodb.ts https://huggingface.co/spaces/helo-ayush/NewIntentExtractor/resolve/main/src/lib/mongodb.ts
4.18 kB
| import mongoose, { type ClientSession } from "mongoose"; | |
| interface MongooseCache { | |
| conn: typeof mongoose | null; | |
| promise: Promise<typeof mongoose> | null; | |
| } | |
| declare global { | |
| var mongoose: MongooseCache | undefined; | |
| } | |
| let cached = global.mongoose; | |
| if (!cached) { | |
| cached = global.mongoose = { conn: null, promise: null }; | |
| } | |
| /** | |
| * Mongoose 9 propagates the active session through AsyncLocalStorage, so | |
| * queries inside withTx() pick it up even if a `{ session }` option is missed. | |
| * The DAL still passes it explicitly — this is a safety net, not the mechanism. | |
| * | |
| * Must be set before connecting. | |
| */ | |
| mongoose.set("transactionAsyncLocalStorage", true); | |
| /** | |
| * autoIndex creates MISSING indexes only — it never alters an existing | |
| * definition, so editing an index in src/models/ is not enough. Run | |
| * `npm run sync-indexes` after any index change. Off in production, where | |
| * building an index on a live collection is a deliberate operation. | |
| */ | |
| mongoose.set("autoIndex", process.env.NODE_ENV !== "production"); | |
| export async function connectToDatabase(): Promise<typeof mongoose> { | |
| const MONGO_URI = process.env.MONGODB_URI || process.env.MONGO_URI; | |
| if (!MONGO_URI) { | |
| throw new Error( | |
| "Please define MONGO_URI or MONGODB_URI in your .env.local file" | |
| ); | |
| } | |
| if (cached!.conn) { | |
| return cached!.conn; | |
| } | |
| if (!cached!.promise) { | |
| cached!.promise = mongoose | |
| .connect(MONGO_URI, { dbName: "sihjantaparty" }) | |
| .then((mongooseInstance) => { | |
| return mongooseInstance; | |
| }); | |
| } | |
| try { | |
| cached!.conn = await cached!.promise; | |
| } catch (e) { | |
| cached!.promise = null; | |
| throw e; | |
| } | |
| return cached!.conn; | |
| } | |
| /* ------------------------------------------------------------------ */ | |
| /* Transactions */ | |
| /* ------------------------------------------------------------------ */ | |
| /** MongoDB's error codeName when the deployment has no replica set. */ | |
| function isNoTransactionSupport(e: unknown): boolean { | |
| const msg = e instanceof Error ? e.message : String(e); | |
| return ( | |
| msg.includes("Transaction numbers are only allowed on a replica set") || | |
| msg.includes("Transactions are not supported") || | |
| msg.includes("IllegalOperation") | |
| ); | |
| } | |
| /** | |
| * Runs `fn` inside a MongoDB transaction, retrying transient errors (mongoose's | |
| * connection.transaction() handles TransientTransactionError and | |
| * UnknownTransactionCommitResult for us). | |
| * | |
| * WHY THIS WRAPPER EXISTS — read before "fixing" a transaction error locally. | |
| * | |
| * Transactions require a replica set. Atlas is one; a bare local `mongod` is | |
| * not, and it fails with "Transaction numbers are only allowed on a replica set | |
| * member or mongos". The tempting five-second fix is to delete the transaction | |
| * wrapper to unblock local work — which silently ships the non-atomic version, | |
| * whose failure modes (a 7-member team, one user on two teams) are | |
| * unrecoverable data corruption discovered mid-hackathon. | |
| * | |
| * So this fails loudly with instructions instead of degrading. There is no | |
| * fallback path on purpose. To develop locally, run a single-node replica set: | |
| * | |
| * mongod --replSet rs0 --dbpath ./data | |
| * mongosh --eval "rs.initiate()" | |
| * | |
| * or point MONGO_URI at Atlas. | |
| */ | |
| export async function withTx<T>( | |
| fn: (session: ClientSession) => Promise<T> | |
| ): Promise<T> { | |
| const conn = await connectToDatabase(); | |
| try { | |
| return await conn.connection.transaction(fn); | |
| } catch (e) { | |
| if (isNoTransactionSupport(e)) { | |
| throw new Error( | |
| "This write needs a MongoDB transaction, but the current deployment " + | |
| "is a standalone server. Transactions require a replica set.\n\n" + | |
| " Local: mongod --replSet rs0 --dbpath ./data\n" + | |
| ' mongosh --eval "rs.initiate()"\n' + | |
| " Or: point MONGO_URI at your Atlas cluster.\n\n" + | |
| "Do NOT remove the transaction to work around this — the writes it " + | |
| "guards are what stop a team reaching 7 members or a user joining " + | |
| "two teams at once.", | |
| { cause: e } | |
| ); | |
| } | |
| throw e; | |
| } | |
| } | |
| export default connectToDatabase; | |