import type { Extension, fetchPayload, onChangePayload, onLoadDocumentPayload, onStoreDocumentPayload, storePayload, } from "@hocuspocus/server"; import * as Y from "yjs"; export interface DatabaseConfiguration { /** * Pass a Promise to retrieve updates from your database. The Promise should resolve to * an array of items with Y.js-compatible binary data. */ fetch: (data: fetchPayload) => Promise; /** * Pass a function to store updates in your database. */ store: (data: storePayload) => Promise; } export class Database implements Extension { /** * Default configuration */ configuration: DatabaseConfiguration = { fetch: async () => null, store: async () => {}, }; /** * Constructor */ constructor(configuration: Partial) { this.configuration = { ...this.configuration, ...configuration, }; } /** * Get stored data from the database. */ async onLoadDocument(data: onLoadDocumentPayload): Promise { const update = await this.configuration.fetch(data); if (update) { Y.applyUpdate(data.document, update); } } /** * Store new updates in the database. */ async onStoreDocument(data: onStoreDocumentPayload) { await this.configuration.store({ ...data, state: Buffer.from(Y.encodeStateAsUpdate(data.document)), }); } }