(options: PersistenceOptions, contentField = 'content')
| 37 | export type PersistenceOptions = LeveldbPersistenceOptions | MongodbPersistenceOptions |
| 38 | |
| 39 | export const initPersistence = async (options: PersistenceOptions, contentField = 'content') => { |
| 40 | let ldb: PersistenceProvider | null = null |
| 41 | const { provider, ...others } = options |
| 42 | if (provider === 'leveldb') { |
| 43 | const { dir = './db' } = others as LeveldbPersistenceOptions |
| 44 | console.info('Persisting documents to "' + dir + '"') |
| 45 | ldb = new LeveldbPersistence(dir) |
| 46 | } else if (provider === 'mongodb') { |
| 47 | const { url, flushSize, ...opts } = others as Omit<MongodbPersistenceOptions, 'provider'> |
| 48 | ldb = new MongodbPersistence(url, { flushSize }, opts) |
| 49 | |
| 50 | console.info('Persisting documents to mongodb') |
| 51 | } |
| 52 | if (!ldb) throw new Error('No persistence provider found') |
| 53 | |
| 54 | persistence = { |
| 55 | provider: ldb, |
| 56 | bindState: async ( |
| 57 | docName, |
| 58 | ydoc, |
| 59 | initialValue = { |
| 60 | children: [{ text: '' }], |
| 61 | }, |
| 62 | ) => { |
| 63 | const persistedYdoc = await ldb!.getYDoc(docName) |
| 64 | const newUpdates = Y.encodeStateAsUpdate(ydoc) |
| 65 | ldb!.storeUpdate(docName, newUpdates) |
| 66 | const content = persistedYdoc.get(contentField, Y.XmlText) as Y.XmlText |
| 67 | const updateContent = ydoc.get(contentField, Y.XmlText) as Y.XmlText |
| 68 | |
| 69 | Y.applyUpdate(ydoc, Y.encodeStateAsUpdate(persistedYdoc)) |
| 70 | ydoc.on('update', update => { |
| 71 | ldb!.storeUpdate(docName, update) |
| 72 | }) |
| 73 | |
| 74 | // init empty content |
| 75 | if (content._length === 0 && updateContent._length === 0) { |
| 76 | ydoc.transact(() => { |
| 77 | updateContent.insertEmbed(0, editorElementToYText(initialValue)) |
| 78 | }) |
| 79 | } |
| 80 | }, |
| 81 | writeState: async (docName, ydoc) => { |
| 82 | // This is called when all connections to the document are closed. |
| 83 | // In the future, this method might also be called in intervals or after a certain number of updates. |
| 84 | return new Promise(resolve => { |
| 85 | // When the returned Promise resolves, the document will be destroyed. |
| 86 | // So make sure that the document really has been written to the database. |
| 87 | resolve() |
| 88 | }) |
| 89 | }, |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | export const setPersistence = (persistence_: Persistence | null) => { |
| 94 | persistence = persistence_ |
no test coverage detected