import * as Y from "yjs"; import {YMapEvent} from "yjs"; type FromIterable = T extends Iterable ? U : never; type FromYMap> = FromIterable["keys"]["entries"]>>; type MapChange = [key:string, { oldValue: T | undefined; newValue: T; action: "add" | "update" | "delete"; origin?: any; }]; /** * Iterate over a Y.Map and yield changes * @param map * @returns */ export async function * yMapIterate = Y.Map>(map: TMap):AsyncGenerator> { const entries = map.toJSON(); console.debug("entries", entries); for (const [key, value] of Object.entries(entries)) { yield [key, { oldValue:undefined, newValue:value, action: "add" as const, }]; } const next = () => new Promise[]>((resolve) => { function onUpdate(event: Y.YMapEvent) { resolve(Array.from(event.keys.entries()).map(([key, value]) => [key, { ...value, origin: event.transaction?.origin, }])); map.unobserve(onUpdate); } map.observe(onUpdate); }) while (true) { const entries = await next(); for (const entry of entries) { yield entry; } } }