| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
- import type { Persistence } from 'y-socket.io/dist/server';
- import * as Y from 'yjs';
- import loggerFactory from '~/utils/logger';
- import type { MongodbPersistence } from './extended/mongodb-persistence';
- const logger = loggerFactory('growi:service:yjs:create-mongodb-persistence');
- /**
- * Based on the example by https://github.com/MaxNoetzold/y-mongodb-provider?tab=readme-ov-file#an-other-example
- * @param mdb
- * @returns
- */
- export const createMongoDBPersistence = (mdb: MongodbPersistence): Persistence => {
- const persistece: Persistence = {
- provider: mdb,
- bindState: async(docName, ydoc) => {
- logger.debug('bindState', { docName });
- const persistedYdoc = await mdb.getYDoc(docName);
- // get the state vector so we can just store the diffs between client and server
- const persistedStateVector = Y.encodeStateVector(persistedYdoc);
- const diff = Y.encodeStateAsUpdate(ydoc, persistedStateVector);
- // store the new data in db (if there is any: empty update is an array of 0s)
- if (diff.reduce((previousValue, currentValue) => previousValue + currentValue, 0) > 0) {
- mdb.storeUpdate(docName, diff);
- mdb.setTypedMeta(docName, 'updatedAt', Date.now());
- }
- // send the persisted data to clients
- Y.applyUpdate(ydoc, Y.encodeStateAsUpdate(persistedYdoc));
- // store updates of the document in db
- ydoc.on('update', async(update) => {
- mdb.storeUpdate(docName, update);
- mdb.setTypedMeta(docName, 'updatedAt', Date.now());
- });
- // cleanup some memory
- persistedYdoc.destroy();
- },
- writeState: async(docName) => {
- logger.debug('writeState', { docName });
- // This is called when all connections to the document are closed.
- // flush document on close to have the smallest possible database
- await mdb.flushDocument(docName);
- },
- };
- return persistece;
- };
|