{"id":16640,"library":"livedb-mongo","title":"MongoDB Adapter for livedb / sharedb","description":"livedb-mongo is a database adapter for `livedb` and its successor, `sharedb`, providing persistent storage and an oplog implementation using MongoDB. While historically named `livedb-mongo`, the project's development has transitioned to primarily support `sharedb`, with its GitHub repository now `sharedb-mongo`. The package is currently at v5.1.0 and maintains an active release cadence, frequently updating to support newer Node.js and MongoDB versions. It stores document snapshots directly in named collections and operations in `COLLECTION_ops`, enabling direct MongoDB queries against the unwrapped JSON documents, which include internal versioning fields (`_v`, `_type`). This adapter is crucial for enabling real-time collaborative applications built with `livedb` or `sharedb`, ensuring operational transformation (OT) works correctly with MongoDB as the backend. It explicitly warns against direct database manipulation outside of the `livedb`/`sharedb` API to prevent data corruption.","status":"active","version":"0.4.1","language":"javascript","source_language":"en","source_url":"git://github.com/share/livedb-mongo","tags":["javascript"],"install":[{"cmd":"npm install livedb-mongo","lang":"bash","label":"npm"},{"cmd":"yarn add livedb-mongo","lang":"bash","label":"yarn"},{"cmd":"pnpm add livedb-mongo","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"This package is an adapter for sharedb (and historically livedb). sharedb is a peer dependency.","package":"sharedb","optional":false},{"reason":"The underlying MongoDB driver used for database interaction. It is a peer dependency.","package":"mongodb","optional":false}],"imports":[{"note":"The primary export is a default function/class, often aliased as `ShareDbMongo` or `livedbmongo`. CommonJS `require` is still widely used in existing `livedb`/`sharedb` applications.","wrong":"import { ShareDbMongo } from 'livedb-mongo';","symbol":"ShareDbMongo","correct":"import ShareDbMongo from 'livedb-mongo'; // For ESM\n// Or for CommonJS:\nconst ShareDbMongo = require('livedb-mongo');"},{"note":"This type definition is for configuring the adapter instance, including options like `disableIndexCreation`.","wrong":"import { SharedbMongoOptions } from 'livedb-mongo';","symbol":"SharedbMongoOptions","correct":"import type { SharedbMongoOptions } from 'livedb-mongo';"},{"note":"While `livedb-mongo` can take a connection string, it can also accept an already initialized `mongodb` `Db` instance for more control.","symbol":"Db","correct":"import { Db } from 'mongodb'; // When passing an existing MongoDB Db instance"}],"quickstart":{"code":"const ShareDbMongo = require('livedb-mongo'); // Or import ShareDbMongo from 'livedb-mongo'; for ESM\nconst livedb = require('livedb'); // This adapter is for livedb (and sharedb)\n\n// MongoDB connection string. Ensure MongoDB is running locally.\n// Replace with your actual MongoDB connection string in production.\nconst mongoUrl = process.env.MONGO_URL || 'mongodb://localhost:27017/livedb_test_db';\n\n// Initialize the livedb-mongo adapter (also known as sharedb-mongo)\n// The second argument is for MongoDB driver options.\nconst mongoAdapter = new ShareDbMongo(mongoUrl, {\n  // Modern driver options, crucial for recent MongoDB versions\n  useUnifiedTopology: true,\n  // replicaSet can be important for change streams if using sharedb's oplog features\n  // replicaSet: 'rs0'\n});\n\n// Initialize livedb client with the mongo adapter\nconst db = livedb.client(mongoAdapter);\n\nconst collection = 'documents';\nconst docId = 'exampleDoc';\n\nconsole.log(`Attempting to connect to MongoDB at ${mongoUrl} via livedb-mongo...`);\n\n// Try to fetch a document. If it doesn't exist, create it.\ndb.fetch(collection, docId, (err, snapshot) => {\n  if (err) {\n    console.error('Error fetching document:', err);\n    mongoAdapter.close(); // Ensure connection is closed on error\n    return;\n  }\n\n  if (snapshot.v === 0) { // Document does not exist (version is 0)\n    console.log(`Document '${docId}' not found. Creating it...`);\n    const initialData = { title: 'Hello World', content: 'This is the initial version.', counter: 0 };\n    db.create(collection, docId, 'json0', initialData, (createErr) => {\n      if (createErr) {\n        console.error('Error creating document:', createErr);\n      } else {\n        console.log(`Document '${docId}' created successfully with data:`, initialData);\n      }\n      mongoAdapter.close(); // Close connection after operation\n    });\n  } else {\n    console.log(`Document '${docId}' found (v${snapshot.v}):`, snapshot.data);\n    // Example: Apply an operation to update the document (e.g., increment counter)\n    const op = { p: ['counter'], na: 1 }; // Operational Transform: Increment 'counter' by 1\n    db.apply(collection, docId, op, { source: 'example_script', version: snapshot.v + 1 }, (applyErr) => {\n      if (applyErr) {\n        console.error('Error applying operation:', applyErr);\n      } else {\n        console.log('Operation applied successfully: counter incremented.');\n        // Fetch again to see the updated state\n        db.fetch(collection, docId, (fetchUpdatedErr, updatedSnapshot) => {\n          if (fetchUpdatedErr) console.error('Error fetching updated document:', fetchUpdatedErr);\n          else console.log('Updated document data:', updatedSnapshot.data);\n          mongoAdapter.close();\n        });\n      }\n    });\n  }\n});","lang":"javascript","description":"Initializes `livedb-mongo` as an adapter for `livedb`, then fetches or creates a document and applies an update operation."},"warnings":[{"fix":"Upgrade Node.js to a supported version (e.g., v18, v20, or newer LTS releases).","message":"Version 5.0.0 of `livedb-mongo` (which is effectively `sharedb-mongo`) dropped support for Node.js v16. Users on Node.js v16 or older must upgrade their Node.js environment to v18 or newer.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Upgrade Node.js to v16 or newer. For v5.x and above, Node.js v18+ is required.","message":"Version 4.0.0 dropped support for Node.js v14. Subsequent versions require Node.js v16 or higher.","severity":"breaking","affected_versions":">=4.0.0 <5.0.0"},{"fix":"Upgrade your MongoDB server to version 3.x or newer and ensure your `mongodb` driver dependency is compatible.","message":"Version 3.0.0 deprecated and subsequently dropped support for `mongodb@2`. Ensure your MongoDB database and driver are at version 3 or newer.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Always use the `livedb` or `sharedb` client API (`db.create`, `db.apply`, etc.) to modify documents managed by `livedb-mongo`.","message":"Editing documents directly in MongoDB outside of the `livedb` (or `sharedb`) API can lead to data corruption or 'weird behaviour' due to the operational transformation (OT) system's reliance on specific document fields and operation sequencing. The adapter adds internal fields like `_v` and `_type` that must be managed by the library.","severity":"gotcha","affected_versions":">=0.4.1"},{"fix":"Manually drop the `src_seq_v` index from your MongoDB collections using `db.collection.dropIndex()` if it's no longer needed after configuring `disableIndexCreation`.","message":"When using the `disableIndexCreation` option for the `src_seq_v` index (introduced in v4.2.0), existing indexes are not automatically removed. If you disable an index that previously existed, you must manually delete it from your MongoDB collection if it's no longer desired.","severity":"gotcha","affected_versions":">=4.2.0"},{"fix":"Upgrade to `livedb-mongo@4.1.1` or newer to resolve the memory leak issue.","message":"Older versions (prior to v4.1.1) had a memory leak when using cursor operations like `$count` or `$explain` with `mongodb@4-6`. This could lead to resource exhaustion in long-running applications.","severity":"gotcha","affected_versions":">=4.0.0 <4.1.1"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Ensure your MongoDB instance is running and accessible from your application's environment. Verify the connection string and firewall rules.","cause":"The MongoDB server is not running or is not accessible at the specified connection URL.","error":"MongoServerSelectionError: connect ECONNREFUSED"},{"fix":"Before creating, use `db.fetch` to check if the document exists (`snapshot.v === 0`). If it does, use `db.apply` to update it, or choose a unique `_id`.","cause":"Attempted to `db.create` a document with an `_id` that already exists in the collection.","error":"Error: Document already exists. Cannot create."},{"fix":"Review the structure of your OT operation. Ensure it correctly targets document paths and uses valid transformations for the document type (e.g., 'json0' for JSON documents).","cause":"The operational transform (OT) operation applied via `db.apply` is malformed or incompatible with the document's current type/data.","error":"Error applying operation: Invalid op"},{"fix":"Upgrade `livedb-mongo` to version 4.1.1 or newer. This issue was fixed in PR #154.","cause":"A bug in older versions of the adapter (prior to v4.1.1) caused `$map` queries to hang indefinitely.","error":"Application hangs when using $map query transform"}],"ecosystem":"npm"}