Skip to content

Instantly share code, notes, and snippets.

@wes5510
Created September 9, 2021 11:20
Show Gist options
  • Save wes5510/9413866d280bbb8b9ded8802a1a27510 to your computer and use it in GitHub Desktop.
Save wes5510/9413866d280bbb8b9ded8802a1a27510 to your computer and use it in GitHub Desktop.
import * as Y from 'yjs';
import { getModelForClass, prop, ReturnModelType } from '@typegoose/typegoose';
const Y_TYPEGOOSE = {
DEFAULT_COLLECTION_NAME: 'ydoc',
TYPE: {
STATE_VECTOR: 'sv',
UPDATE: 'update',
META: 'meta',
},
};
enum Type {
STATE_VECTOR = 'sv',
UPDATE = 'update',
META = 'meta',
}
class YDoc {
@prop({ required: true, index: true })
name!: string;
@prop({ required: true, enum: Type })
type!: string;
@prop({ required: true })
value!: Buffer;
}
let YDocModel: ReturnModelType<typeof YDoc>;
const createModel = (
collection = Y_TYPEGOOSE.DEFAULT_COLLECTION_NAME,
): void => {
YDocModel = getModelForClass(YDoc, {
schemaOptions: { collection },
});
};
const getUpdates = async (name: string): Promise<Uint8Array[]> => {
const updates = await YDocModel.find({ name, type: 'update' })
.sort({ _id: -1 })
.select({ value: 1 });
return updates.map((update) => new Uint8Array(update.value));
};
const getYDoc = async (name: string): Promise<Y.Doc> => {
const updates = await getUpdates(name);
const ydoc = new Y.Doc();
ydoc.transact(() => {
for (let i = 0; i < updates.length; i++) {
Y.applyUpdate(ydoc, updates[i]);
}
});
return ydoc;
};
const isExistsDoc = async (name: string): Promise<boolean> => {
const ret = await YDocModel.exists({ name });
return ret;
};
const storeUpdate = async (name: string, value: Uint8Array): Promise<void> => {
const existsDoc = await isExistsDoc(name);
if (!existsDoc) {
const ydoc = new Y.Doc();
Y.applyUpdate(ydoc, value);
const sv = Y.encodeStateVector(ydoc);
await new YDocModel({
name,
type: Y_TYPEGOOSE.TYPE.STATE_VECTOR,
value: Buffer.from(sv),
}).save();
}
await new YDocModel({
name,
type: Y_TYPEGOOSE.TYPE.UPDATE,
value: Buffer.from(value),
}).save();
};
const clearDocument = async (name: string): Promise<void> => {
await YDocModel.deleteMany({ name });
};
export default {
createModel,
getYDoc,
storeUpdate,
clearDocument,
};
@wes5510
Copy link
Author

wes5510 commented Sep 9, 2021

Using

yTypegoose.createModel('nodes');

const docId = 'node-1';
const doc = new Y.Doc();
await yTypegoose.storeUpdate(docId, Y.encodeStateAsUpdate(doc));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment