MongoDB Persistence Provider for Yjs

0.2.1 · active · verified Wed Apr 22

y-mongodb-provider is a database adapter that enables persistent storage and retrieval of Yjs collaborative documents using MongoDB. It serves as a backend for y-websocket servers, allowing Yjs document states to be saved and loaded, thereby ensuring data durability across server restarts or disconnections. The current stable version is 0.2.1, with updates primarily focused on dependency management, internal driver improvements, and bug fixes, indicating an active development status though without a strict release cadence. Key differentiators include its specific integration with MongoDB (unlike Yjs's officially supported y-leveldb), its ability to handle Yjs updates exceeding MongoDB's 16MB document size limit (since v0.1.8), and its use of the official MongoDB Node.js Driver for enhanced security and performance. It's important to note that this package is not officially supported by the Yjs team.

Warnings

Install

Imports

Quickstart

This example sets up a Yjs WebSocket server using `y-websocket` and integrates `y-mongodb-provider` for persistent storage of Yjs document states in a MongoDB database. It demonstrates binding document state on connection and asynchronously storing updates as they occur.

import http from 'http';
import { WebSocketServer } from 'ws';
import * as Y from 'yjs';
import { MongodbPersistence } from 'y-mongodb-provider';
import yUtils from 'y-websocket/bin/utils'; // Note: y-websocket/bin/utils is an internal utility, adapt as needed.

const port = process.env.PORT || 1234;
const mongoConnectionString = process.env.MONGODB_URL || 'mongodb://localhost:27017/yjstest';

const server = http.createServer((request, response) => {
	response.writeHead(200, { 'Content-Type': 'text/plain' });
	response.end('okay');
});

// Initialize Yjs WebSocket server
const wss = new WebSocketServer({ server });
wss.on('connection', yUtils.setupWSConnection);

// Initialize MongoDB persistence for Yjs
const mdb = new MongodbPersistence(mongoConnectionString, {
	collectionName: 'transactions',
	flushSize: 100,
	multipleCollections: false, // Default; set to true if each document needs its own collection
});

// Set up persistence with y-websocket
yUtils.setPersistence({
	bindState: async (docName, ydoc) => {
		// Retrieve the persisted document state
		const persistedYdoc = await mdb.getYDoc(docName);
		
		// Apply the persisted state to the current ydoc
		Y.applyUpdate(ydoc, Y.encodeStateAsUpdate(persistedYdoc));

		// Store initial state and listen for future updates
		mdb.storeUpdate(docName, Y.encodeStateAsUpdate(ydoc));
		ydoc.on('update', async (update) => {
			mdb.storeUpdate(docName, update);
		});
	},
	writeState: async (docName, ydoc) => {
		// This function is called when all connections to a document are closed.
		// Ensure all pending updates are written to the database.
		// For y-mongodb-provider, `storeUpdate` handles this incrementally.
		// The promise resolution signals that the document can be destroyed.
		return new Promise(resolve => resolve());
	},
});

server.listen(port, () => {
	console.log(`Yjs WebSocket server with MongoDB persistence listening on port: ${port}`);
});

view raw JSON →