UNPKG

y-mongodb-provider

Version:
1 lines 41.7 kB
{"version":3,"file":"y-mongodb.cjs","sources":["../src/mongo-adapter.js","../src/utils.js","../src/y-mongodb.js"],"sourcesContent":["import { MongoClient } from 'mongodb';\n\n/**\n * Parse a MongoDB connection string and return the database name.\n *\n * @param {string} connectionString\n * @returns {string}\n */\nfunction getMongoDbDatabaseName(connectionString) {\n\tconst url = new URL(connectionString);\n\tconst database = url.pathname.slice(1);\n\treturn database;\n}\n\nexport class MongoAdapter {\n\t/**\n\t * Create a MongoAdapter instance.\n\t * @param {string|{client: MongoClient, db: import('mongodb').Db}} dbConnection A MongoDB connection string or an object containing a MongoClient instance (`client`) and a database instance (`db`).\n\t * @param {object} opts\n\t * @param {string} opts.collection Name of the collection where all documents are stored.\n\t * @param {boolean} opts.multipleCollections When set to true, each document gets an own\n\t * collection (instead of all documents stored in the same one).\n\t * When set to true, the option $collection gets ignored.\n\t */\n\tconstructor(dbConnection, { collection, multipleCollections }) {\n\t\tthis.collection = collection;\n\t\tthis.multipleCollections = multipleCollections;\n\n\t\tif (typeof dbConnection === 'string') {\n\t\t\t// Connection string logic\n\t\t\tconst databaseName = getMongoDbDatabaseName(dbConnection);\n\t\t\tthis.client = new MongoClient(dbConnection);\n\t\t\tthis.db = this.client.db(databaseName);\n\t\t} else if (typeof dbConnection === 'object' && dbConnection.client && dbConnection.db) {\n\t\t\t// Connection object logic\n\t\t\tthis.client = dbConnection.client;\n\t\t\tthis.db = dbConnection.db;\n\t\t} else {\n\t\t\tthrow new Error(\n\t\t\t\t'Invalid dbConnection. Must be a connection string or an object with client and db.',\n\t\t\t);\n\t\t}\n\n\t\t/*\n\t\t\tNOTE: client.connect() is optional since v4.7\n\t\t\t\"However, MongoClient.connect can still be called manually and remains useful for\n\t\t\tlearning about misconfiguration (auth, server not started, connection string correctness)\n\t\t\tearly in your application's startup.\"\n\n\t\t\tI will not use it for now, but may change that in the future.\n\t\t*/\n\t}\n\n\t/**\n\t * Get the MongoDB collection name for any docName\n\t * @param {import('mongodb').Filter<import('mongodb').Document>} query\n\t * @returns {string} collectionName\n\t */\n\t_getCollectionName({ docName }) {\n\t\tif (this.multipleCollections) {\n\t\t\treturn docName;\n\t\t} else {\n\t\t\treturn this.collection;\n\t\t}\n\t}\n\n\t/**\n\t *\n\t * @param {import('mongodb').Filter<import('mongodb').Document>} query\n\t * @param {{limit?: number; reverse?: boolean;}} [options]\n\t * @returns {Promise<import('mongodb').WithId<import('mongodb').Document>[]>}\n\t */\n\tfind(query, options) {\n\t\tconst { limit = 0, reverse = false } = options || {};\n\n\t\t/** @type {{ clock: 1 | -1, part: 1 | -1 }} */\n\t\tconst sortQuery = reverse ? { clock: -1, part: 1 } : { clock: 1, part: 1 };\n\n\t\tconst collection = this.db.collection(this._getCollectionName(query));\n\t\treturn collection.find(query, { limit, sort: sortQuery }).toArray();\n\t}\n\n\t/**\n\t * Apply a $query and get one document from MongoDB.\n\t * @param {import('mongodb').Filter<import('mongodb').Document>} query\n\t * @param {{limit?: number; reverse?: boolean;}} [options]\n\t * @returns {Promise<import('mongodb').WithId<import('mongodb').Document> | null>}\n\t */\n\tfindOne(query, options) {\n\t\treturn this.find(query, options).then((docs) => docs[0] || null);\n\t}\n\n\t/**\n\t * Store one document in MongoDB.\n\t * @param {import('mongodb').Filter<import('mongodb').Document>} query\n\t * @param {import('mongodb').UpdateFilter<import('mongodb').Document>} values\n\t * @returns {Promise<import('mongodb').WithId<import('mongodb').Document> | null>} Stored document\n\t */\n\tasync put(query, values) {\n\t\tif (!query.docName || !query.version || !values.value) {\n\t\t\tthrow new Error('Document and version must be provided');\n\t\t}\n\n\t\tconst collection = this.db.collection(this._getCollectionName(query));\n\n\t\tawait collection.updateOne(query, { $set: values }, { upsert: true });\n\t\treturn this.findOne(query);\n\t}\n\n\t/**\n\t * Removes all documents that fit the $query\n\t * @param {import('mongodb').Filter<import('mongodb').Document>} query\n\t * @returns {Promise<import('mongodb').BulkWriteResult>} Contains status of the operation\n\t */\n\tdelete(query) {\n\t\tconst collection = this.db.collection(this._getCollectionName(query));\n\n\t\t/*\n\t\t\tNote from mongodb v4.7 release notes:\n\t\t\t\"It's a known limitation that explicit sessions (client.startSession) and\n\t\t\tinitializeOrderedBulkOp, initializeUnorderedBulkOp cannot be used until\n\t\t\tMongoClient.connect is first called.\n\t\t\tLook forward to a future patch release that will correct these inconsistencies.\"\n\n\t\t\tI dont know yet if this is a problem for me here.\n\t\t*/\n\t\tconst bulk = collection.initializeOrderedBulkOp();\n\t\tbulk.find(query).delete();\n\t\treturn bulk.execute();\n\t}\n\n\t/**\n\t * Close connection to MongoDB instance.\n\t */\n\tasync close() {\n\t\tawait this.client.close();\n\t}\n\n\t/**\n\t * Get all collection names stored on the MongoDB instance.\n\t * @returns {Promise<string[]>}\n\t */\n\tasync getCollectionNames() {\n\t\tconst collectionInfos = await this.db.listCollections().toArray();\n\t\treturn collectionInfos.map((c) => c.name);\n\t}\n\n\t/**\n\t * Delete database\n\t */\n\tasync flush() {\n\t\tawait this.db.dropDatabase();\n\t\tawait this.client.close();\n\t}\n\n\t/**\n\t * Delete collection\n\t * @param {string} collectionName\n\t */\n\tdropCollection(collectionName) {\n\t\treturn this.db.collection(collectionName).drop();\n\t}\n}\n","import * as Y from 'yjs';\nimport * as binary from 'lib0/binary';\nimport * as encoding from 'lib0/encoding';\nimport * as decoding from 'lib0/decoding';\nimport { Buffer } from 'buffer';\n\nexport const PREFERRED_TRIM_SIZE = 400;\nconst MAX_DOCUMENT_SIZE = 15000000; // ~15MB (plus space for metadata)\n\n/**\n * Remove all documents from db with Clock between $from and $to\n *\n * @param {import('./mongo-adapter.js').MongoAdapter} db\n * @param {string} docName\n * @param {number} from Greater than or equal\n * @param {number} to lower than (not equal)\n * @returns {Promise<import('mongodb').BulkWriteResult>} Contains status of the operation\n */\nexport const clearUpdatesRange = async (db, docName, from, to) =>\n\tdb.delete({\n\t\tdocName,\n\t\tclock: {\n\t\t\t$gte: from,\n\t\t\t$lt: to,\n\t\t},\n\t});\n\n/**\n * Create a unique key for a update message.\n * @param {string} docName\n * @param {number} [clock] must be unique\n * @return {{version: \"v1\"; docName: string; action: \"update\"; clock?: number; }}\n */\nconst createDocumentUpdateKey = (docName, clock) => {\n\tif (clock !== undefined) {\n\t\treturn {\n\t\t\tversion: 'v1',\n\t\t\taction: 'update',\n\t\t\tdocName,\n\t\t\tclock,\n\t\t};\n\t} else {\n\t\treturn {\n\t\t\tversion: 'v1',\n\t\t\taction: 'update',\n\t\t\tdocName,\n\t\t};\n\t}\n};\n\n/**\n * We have a separate state vector key so we can iterate efficiently over all documents\n * @param {string} docName\n * @return {{docName: string; version: \"v1_sv\"}}\n */\nexport const createDocumentStateVectorKey = (docName) => ({\n\tdocName,\n\tversion: 'v1_sv',\n});\n\n/**\n * @param {string} docName\n * @param {string} metaKey\n * @return {{docName: string; version: \"v1\"; metaKey: string; }}\n */\nexport const createDocumentMetaKey = (docName, metaKey) => ({\n\tversion: 'v1',\n\tdocName,\n\tmetaKey: `meta_${metaKey}`,\n});\n\n/**\n * @param {import('./mongo-adapter.js').MongoAdapter} db\n * @return {Promise<void>}\n */\nexport const flushDB = (db) => db.flush();\n\n/**\n *\n * This function converts MongoDB updates to a buffer that can be processed by the application.\n * It handles both complete documents and large documents that have been split into smaller 'parts' due to MongoDB's size limit.\n * For split documents, it collects all the parts and merges them together.\n * It assumes that the parts of a split document are ordered and located exactly after the document with part number 1.\n *\n * @param {{ _id: import(\"mongodb\").ObjectId; action: string; version: string; docName: string; clock: number; part?: number; value: import(\"mongodb\").Binary; }[]} docs\n * @return {Uint8Array[]}\n */\nconst convertMongoUpdates = (docs) => {\n\tif (!Array.isArray(docs) || !docs.length) return [];\n\n\t/** @type {Uint8Array[]} */\n\tconst updates = [];\n\tfor (let i = 0; i < docs.length; i++) {\n\t\tconst doc = docs[i];\n\t\tif (!doc.part) {\n\t\t\tupdates.push(doc.value.buffer);\n\t\t} else if (doc.part === 1) {\n\t\t\t// merge the docs together that got split because of mongodb size limits\n\t\t\tconst parts = [doc.value.buffer];\n\t\t\tlet j;\n\t\t\tlet currentPartId = doc.part;\n\t\t\tfor (j = i + 1; j < docs.length; j++) {\n\t\t\t\tconst part = docs[j];\n\t\t\t\tif (part.part && part.clock === doc.clock) {\n\t\t\t\t\tif (currentPartId !== part.part - 1) {\n\t\t\t\t\t\tthrow new Error('Couldnt merge updates together because a part is missing!');\n\t\t\t\t\t}\n\t\t\t\t\tparts.push(part.value.buffer);\n\t\t\t\t\tcurrentPartId = part.part;\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tupdates.push(Buffer.concat(parts));\n\t\t\t// set i to j - 1 because we already processed all parts\n\t\t\ti = j - 1;\n\t\t}\n\t}\n\treturn updates;\n};\n\n/**\n * Get all document updates for a specific document.\n *\n * @param {import('./mongo-adapter.js').MongoAdapter} db\n * @param {string} docName\n * @return {Promise<Uint8Array[]>}\n */\nexport const getMongoUpdates = async (db, docName) => {\n\tconst docs = await db.find(createDocumentUpdateKey(docName));\n\t// TODO: I dont know how to type this without actual typescript\n\t// @ts-ignore\n\treturn convertMongoUpdates(docs);\n};\n\n/**\n * @param {import('./mongo-adapter.js').MongoAdapter} db\n * @param {string} docName\n * @return {Promise<number>} Returns -1 if this document doesn't exist yet\n */\nexport const getCurrentUpdateClock = (db, docName) =>\n\tdb\n\t\t.findOne(\n\t\t\t{\n\t\t\t\t...createDocumentUpdateKey(docName, 0),\n\t\t\t\tclock: {\n\t\t\t\t\t$gte: 0,\n\t\t\t\t\t$lt: binary.BITS32,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ reverse: true },\n\t\t)\n\t\t.then((update) => {\n\t\t\tif (!update) {\n\t\t\t\treturn -1;\n\t\t\t} else {\n\t\t\t\treturn update.clock;\n\t\t\t}\n\t\t});\n\n/**\n * @param {import('./mongo-adapter.js').MongoAdapter} db\n * @param {string} docName\n * @param {Uint8Array} sv state vector\n * @param {number} clock current clock of the document so we can determine\n * when this statevector was created\n */\nconst writeStateVector = async (db, docName, sv, clock) => {\n\tconst encoder = encoding.createEncoder();\n\tencoding.writeVarUint(encoder, clock);\n\tencoding.writeVarUint8Array(encoder, sv);\n\tawait db.put(createDocumentStateVectorKey(docName), {\n\t\tvalue: encoding.toUint8Array(encoder),\n\t});\n};\n\n/**\n * @param {import('./mongo-adapter.js').MongoAdapter} db\n * @param {string} docName\n * @param {Uint8Array} update\n * @return {Promise<number>} Returns the clock of the stored update\n */\nexport const storeUpdate = async (db, docName, update) => {\n\tconst clock = await getCurrentUpdateClock(db, docName);\n\tif (clock === -1) {\n\t\t// make sure that a state vector is always written, so we can search for available documents\n\t\tconst ydoc = new Y.Doc();\n\t\tY.applyUpdate(ydoc, update);\n\t\tconst sv = Y.encodeStateVector(ydoc);\n\t\tawait writeStateVector(db, docName, sv, 0);\n\t}\n\n\t// mongodb has a maximum document size of 16MB;\n\t// if our buffer exceeds it, we store the update in multiple documents\n\tif (update.length <= MAX_DOCUMENT_SIZE) {\n\t\tawait db.put(createDocumentUpdateKey(docName, clock + 1), {\n\t\t\tvalue: update,\n\t\t});\n\t} else {\n\t\tconst totalChunks = Math.ceil(update.length / MAX_DOCUMENT_SIZE);\n\n\t\tconst putPromises = [];\n\t\tfor (let i = 0; i < totalChunks; i++) {\n\t\t\tconst start = i * MAX_DOCUMENT_SIZE;\n\t\t\tconst end = Math.min(start + MAX_DOCUMENT_SIZE, update.length);\n\t\t\tconst chunk = update.subarray(start, end);\n\n\t\t\tputPromises.push(\n\t\t\t\tdb.put({ ...createDocumentUpdateKey(docName, clock + 1), part: i + 1 }, { value: chunk }),\n\t\t\t);\n\t\t}\n\n\t\tawait Promise.all(putPromises);\n\t}\n\n\treturn clock + 1;\n};\n\n/**\n * For now this is a helper method that creates a Y.Doc and then re-encodes a document update.\n * In the future this will be handled by Yjs without creating a Y.Doc (constant memory consumption).\n *\n * @param {Array<Uint8Array>} updates\n * @return {{update:Uint8Array, sv: Uint8Array}}\n */\nexport const mergeUpdates = (updates) => {\n\tconst ydoc = new Y.Doc();\n\tydoc.transact(() => {\n\t\tfor (let i = 0; i < updates.length; i++) {\n\t\t\tY.applyUpdate(ydoc, updates[i]);\n\t\t}\n\t});\n\treturn { update: Y.encodeStateAsUpdate(ydoc), sv: Y.encodeStateVector(ydoc) };\n};\n\n/**\n * @param {import(\"mongodb\").Binary} buf\n * @return {{ sv: Uint8Array, clock: number }}\n */\nexport const decodeMongodbStateVector = (buf) => {\n\tlet decoder;\n\tif (Buffer.isBuffer(buf)) {\n\t\tdecoder = decoding.createDecoder(buf);\n\t} else if (Buffer.isBuffer(buf?.buffer)) {\n\t\tdecoder = decoding.createDecoder(buf.buffer);\n\t} else {\n\t\tthrow new Error('No buffer provided at decodeMongodbStateVector()');\n\t}\n\tconst clock = decoding.readVarUint(decoder);\n\tconst sv = decoding.readVarUint8Array(decoder);\n\treturn { sv, clock };\n};\n\n/**\n * @param {import('./mongo-adapter.js').MongoAdapter} db\n * @param {string} docName\n */\nexport const readStateVector = async (db, docName) => {\n\tconst doc = await db.findOne({ ...createDocumentStateVectorKey(docName) });\n\tif (!doc?.value) {\n\t\t// no state vector created yet or no document exists\n\t\treturn { sv: null, clock: -1 };\n\t}\n\treturn decodeMongodbStateVector(doc.value);\n};\n\n/**\n *\n * @param {import('./mongo-adapter.js').MongoAdapter} db\n */\nexport const getAllSVDocs = async (db) => db.find({ version: 'v1_sv' });\n\n/**\n * Merge all MongoDB documents of the same yjs document together.\n * @param {import('./mongo-adapter.js').MongoAdapter} db\n * @param {string} docName\n * @param {Uint8Array} stateAsUpdate\n * @param {Uint8Array} stateVector\n * @return {Promise<number>} returns the clock of the flushed doc\n */\nexport const flushDocument = async (db, docName, stateAsUpdate, stateVector) => {\n\tconst clock = await storeUpdate(db, docName, stateAsUpdate);\n\tawait writeStateVector(db, docName, stateVector, clock);\n\tawait clearUpdatesRange(db, docName, 0, clock);\n\treturn clock;\n};\n","import * as Y from 'yjs';\nimport * as binary from 'lib0/binary';\nimport * as promise from 'lib0/promise';\nimport { MongoAdapter } from './mongo-adapter.js';\nimport * as U from './utils.js';\n\nexport class MongodbPersistence {\n\t/**\n\t * Create a y-mongodb persistence instance.\n\t * @param {string|{client: import('mongodb').MongoClient, db: import('mongodb').Db}} connectionObj A MongoDB connection string or an object containing a MongoClient instance (`client`) and a database instance (`db`).\n\t * @param {object} [opts] Additional optional parameters.\n\t * @param {string} [opts.collectionName] Name of the collection where all\n\t * documents are stored. Default: \"yjs-writings\"\n\t * @param {boolean} [opts.multipleCollections] When set to true, each document gets\n\t * an own collection (instead of all documents stored in the same one). When set to true,\n\t * the option collectionName gets ignored. Default: false\n\t * @param {number} [opts.flushSize] The number of stored transactions needed until\n\t * they are merged automatically into one Mongodb document. Default: 400\n\t */\n\tconstructor(connectionObj, opts = {}) {\n\t\tconst { collectionName = 'yjs-writings', multipleCollections = false, flushSize = 400 } = opts;\n\t\tif (typeof collectionName !== 'string' || !collectionName) {\n\t\t\tthrow new Error(\n\t\t\t\t'Constructor option \"collectionName\" is not a valid string. Either dont use this option (default is \"yjs-writings\") or use a valid string! Take a look into the Readme for more information: https://github.com/MaxNoetzold/y-mongodb-provider#persistence--mongodbpersistenceconnectionlink-string-options-object',\n\t\t\t);\n\t\t}\n\t\tif (typeof multipleCollections !== 'boolean') {\n\t\t\tthrow new Error(\n\t\t\t\t'Constructor option \"multipleCollections\" is not a boolean. Either dont use this option (default is \"false\") or use a valid boolean! Take a look into the Readme for more information: https://github.com/MaxNoetzold/y-mongodb-provider#persistence--mongodbpersistenceconnectionlink-string-options-object',\n\t\t\t);\n\t\t}\n\t\tif (typeof flushSize !== 'number' || flushSize <= 0) {\n\t\t\tthrow new Error(\n\t\t\t\t'Constructor option \"flushSize\" is not a valid number. Either dont use this option (default is \"400\") or use a valid number larger than 0! Take a look into the Readme for more information: https://github.com/MaxNoetzold/y-mongodb-provider#persistence--mongodbpersistenceconnectionlink-string-options-object',\n\t\t\t);\n\t\t}\n\t\tconst db = new MongoAdapter(connectionObj, {\n\t\t\tcollection: collectionName,\n\t\t\tmultipleCollections,\n\t\t});\n\t\tthis.flushSize = flushSize ?? U.PREFERRED_TRIM_SIZE;\n\t\tthis.multipleCollections = multipleCollections;\n\n\t\t// scope the queue of the transaction to each docName\n\t\t// -> this should allow concurrency for different rooms\n\t\t// Idea and adjusted code from: https://github.com/fadiquader/y-mongodb/issues/10\n\t\tthis.tr = {};\n\n\t\t/**\n\t\t * Execute an transaction on a database. This will ensure that other processes are\n\t\t * currently not writing.\n\t\t *\n\t\t * This is a private method and might change in the future.\n\t\t *\n\t\t * @template T\n\t\t *\n\t\t * @param {function(MongoAdapter):Promise<T>} f A transaction that receives the db object\n\t\t * @return {Promise<T>}\n\t\t */\n\t\tthis._transact = (docName, f) => {\n\t\t\tif (!this.tr[docName]) {\n\t\t\t\tthis.tr[docName] = promise.resolve();\n\t\t\t}\n\n\t\t\tconst currTr = this.tr[docName];\n\t\t\tlet nextTr = null;\n\n\t\t\tnextTr = (async () => {\n\t\t\t\tawait currTr;\n\n\t\t\t\tlet res = /** @type {any} */ (null);\n\t\t\t\ttry {\n\t\t\t\t\tres = await f(db);\n\t\t\t\t} catch (err) {\n\t\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\t\tconsole.warn('Error during saving transaction', err);\n\t\t\t\t}\n\n\t\t\t\t// once the last transaction for a given docName resolves, remove it from the queue\n\t\t\t\tif (this.tr[docName] === nextTr) {\n\t\t\t\t\tdelete this.tr[docName];\n\t\t\t\t}\n\n\t\t\t\treturn res;\n\t\t\t})();\n\n\t\t\tthis.tr[docName] = nextTr;\n\n\t\t\treturn this.tr[docName];\n\t\t};\n\t}\n\n\t/**\n\t * Create a Y.Doc instance with the data persistet in mongodb.\n\t * Use this to temporarily create a Yjs document to sync changes or extract data.\n\t *\n\t * @param {string} docName\n\t * @return {Promise<Y.Doc>}\n\t */\n\tgetYDoc(docName) {\n\t\treturn this._transact(docName, async (db) => {\n\t\t\tconst updates = await U.getMongoUpdates(db, docName);\n\t\t\tconst ydoc = new Y.Doc();\n\t\t\tydoc.transact(() => {\n\t\t\t\tfor (let i = 0; i < updates.length; i++) {\n\t\t\t\t\tY.applyUpdate(ydoc, updates[i]);\n\t\t\t\t}\n\t\t\t});\n\t\t\tif (updates.length > this.flushSize) {\n\t\t\t\tawait U.flushDocument(db, docName, Y.encodeStateAsUpdate(ydoc), Y.encodeStateVector(ydoc));\n\t\t\t}\n\t\t\treturn ydoc;\n\t\t});\n\t}\n\n\t/**\n\t * Store a single document update to the database.\n\t *\n\t * @param {string} docName\n\t * @param {Uint8Array} update\n\t * @return {Promise<number>} Returns the clock of the stored update\n\t */\n\tstoreUpdate(docName, update) {\n\t\treturn this._transact(docName, (db) => U.storeUpdate(db, docName, update));\n\t}\n\n\t/**\n\t * The state vector (describing the state of the persisted document - see https://github.com/yjs/yjs#Document-Updates) is maintained in a separate field and constantly updated.\n\t *\n\t * This allows you to sync changes without actually creating a Yjs document.\n\t *\n\t * @param {string} docName\n\t * @return {Promise<Uint8Array>}\n\t */\n\tgetStateVector(docName) {\n\t\treturn this._transact(docName, async (db) => {\n\t\t\tconst { clock, sv } = await U.readStateVector(db, docName);\n\t\t\tlet curClock = -1;\n\t\t\tif (sv !== null) {\n\t\t\t\tcurClock = await U.getCurrentUpdateClock(db, docName);\n\t\t\t}\n\t\t\tif (sv !== null && clock === curClock) {\n\t\t\t\treturn sv;\n\t\t\t} else {\n\t\t\t\t// current state vector is outdated\n\t\t\t\tconst updates = await U.getMongoUpdates(db, docName);\n\t\t\t\tconst { update, sv: newSv } = U.mergeUpdates(updates);\n\t\t\t\tawait U.flushDocument(db, docName, update, newSv);\n\t\t\t\treturn newSv;\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Get the differences directly from the database.\n\t * The same as Y.encodeStateAsUpdate(ydoc, stateVector).\n\t * @param {string} docName\n\t * @param {Uint8Array} stateVector\n\t */\n\tasync getDiff(docName, stateVector) {\n\t\tconst ydoc = await this.getYDoc(docName);\n\t\treturn Y.encodeStateAsUpdate(ydoc, stateVector);\n\t}\n\n\t/**\n\t * Delete a document, and all associated data from the database.\n\t * When option multipleCollections is set, it removes the corresponding collection\n\t * @param {string} docName\n\t * @return {Promise<void>}\n\t */\n\tclearDocument(docName) {\n\t\treturn this._transact(docName, async (db) => {\n\t\t\tif (!this.multipleCollections) {\n\t\t\t\tawait db.delete(U.createDocumentStateVectorKey(docName));\n\t\t\t\tawait U.clearUpdatesRange(db, docName, 0, binary.BITS32);\n\t\t\t} else {\n\t\t\t\tawait db.dropCollection(docName);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Persist some meta information in the database and associate it\n\t * with a document. It is up to you what you store here.\n\t * You could, for example, store credentials here.\n\t *\n\t * @param {string} docName\n\t * @param {string} metaKey\n\t * @param {any} value\n\t * @return {Promise<void>}\n\t */\n\tsetMeta(docName, metaKey, value) {\n\t\t/*\tUnlike y-leveldb, we simply store the value here without encoding\n\t \t\t it in a buffer beforehand. */\n\t\treturn this._transact(docName, async (db) => {\n\t\t\tawait db.put(U.createDocumentMetaKey(docName, metaKey), { value });\n\t\t});\n\t}\n\n\t/**\n\t * Retrieve a store meta value from the database. Returns undefined if the\n\t * metaKey doesn't exist.\n\t *\n\t * @param {string} docName\n\t * @param {string} metaKey\n\t * @return {Promise<any>}\n\t */\n\tgetMeta(docName, metaKey) {\n\t\treturn this._transact(docName, async (db) => {\n\t\t\tconst res = await db.findOne({\n\t\t\t\t...U.createDocumentMetaKey(docName, metaKey),\n\t\t\t});\n\t\t\tif (!res?.value) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\treturn res.value;\n\t\t});\n\t}\n\n\t/**\n\t * Delete a store meta value.\n\t *\n\t * @param {string} docName\n\t * @param {string} metaKey\n\t * @return {Promise<any>}\n\t */\n\tdelMeta(docName, metaKey) {\n\t\treturn this._transact(docName, (db) =>\n\t\t\tdb.delete({\n\t\t\t\t...U.createDocumentMetaKey(docName, metaKey),\n\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Retrieve the names of all stored documents.\n\t *\n\t * @return {Promise<string[]>}\n\t */\n\tgetAllDocNames() {\n\t\treturn this._transact('global', async (db) => {\n\t\t\tif (this.multipleCollections) {\n\t\t\t\t// get all collection names from db\n\t\t\t\treturn db.getCollectionNames();\n\t\t\t} else {\n\t\t\t\t// when all docs are stored in the same collection we just need to get all\n\t\t\t\t// statevectors and return their names\n\t\t\t\tconst docs = await U.getAllSVDocs(db);\n\t\t\t\treturn docs.map((doc) => doc.docName);\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Retrieve the state vectors of all stored documents.\n\t * You can use this to sync two y-mongodb instances.\n\t * !Note: The state vectors might be outdated if the associated document\n\t * is not yet flushed. So use with caution.\n\t * @return {Promise<{ name: string, sv: Uint8Array, clock: number }[]>}\n\t */\n\tgetAllDocStateVectors() {\n\t\treturn this._transact('global', async (db) => {\n\t\t\tconst docs = await U.getAllSVDocs(db);\n\t\t\treturn docs.map((doc) => {\n\t\t\t\tconst { sv, clock } = U.decodeMongodbStateVector(doc.value);\n\t\t\t\treturn { name: doc.docName, sv, clock };\n\t\t\t});\n\t\t});\n\t}\n\n\t/**\n\t * Internally y-mongodb stores incremental updates. You can merge all document\n\t * updates to a single entry. You probably never have to use this.\n\t * It is done automatically every $options.flushsize (default 400) transactions.\n\t *\n\t * @param {string} docName\n\t * @return {Promise<void>}\n\t */\n\tflushDocument(docName) {\n\t\treturn this._transact(docName, async (db) => {\n\t\t\tconst updates = await U.getMongoUpdates(db, docName);\n\t\t\tconst { update, sv } = U.mergeUpdates(updates);\n\t\t\tawait U.flushDocument(db, docName, update, sv);\n\t\t});\n\t}\n\n\t/**\n\t * Delete the whole yjs mongodb\n\t * @return {Promise<void>}\n\t */\n\tflushDB() {\n\t\treturn this._transact('global', async (db) => {\n\t\t\tawait U.flushDB(db);\n\t\t});\n\t}\n\n\t/**\n\t * Closes open database connection\n\t * @returns {Promise<void>}\n\t */\n\tdestroy() {\n\t\treturn this._transact('global', async (db) => {\n\t\t\tawait db.close();\n\t\t});\n\t}\n}\n"],"names":["MongoClient","Buffer","binary","encoding","Y","decoding","U.PREFERRED_TRIM_SIZE","promise","U.getMongoUpdates","U.flushDocument","U.storeUpdate","U.readStateVector","U.getCurrentUpdateClock","U.mergeUpdates","U.createDocumentStateVectorKey","U.clearUpdatesRange","U.createDocumentMetaKey","U.getAllSVDocs","U.decodeMongodbStateVector","U.flushDB"],"mappings":"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"}