// fixtures/changes.mjs — what a transaction on the slides root means // for the editor. Three kinds, and each has one consumer: // // text a text or notes fragment on a slide changed. Nothing to // redraw: y-prosemirror already did, in every bound view. // The strip re-fetches that slide's thumbnail. // structure a slide's map, a block, its props, region, box or z // changed. The stage re-fetches the section when it is the // current slide; the strip re-fetches the thumbnail. // order the slide list itself changed: a slide added, removed or // moved. The strip re-syncs its items. // // The classification is the walk from an event's target up to the // slide map whose parent is the slides array: pass through an Xml type // on the way and it was text, otherwise structure; start AT the array // and it was the order. One more case since the deck's order became // data: a slide's own `order` key (ydoc.mjs, "reading order") is the // deck's order, and move_slide writes it rather than moving array // entries, so a reorder arrives as a key change on every slide map and // not as an event on the array at all. Pure over Yjs types, driven in // changes.test.mjs with real observeDeep events. import * as Y from 'yjs' import { getString } from './ydoc.mjs' /** {text: [slideId], structure: [slideId], order: bool} for one transaction's deep events. */ export function classify (events, slides) { const text = new Set() const structure = new Set() let order = false for (const e of events) { let node = e.target if (node === slides) { order = true continue } let isText = false while (node && node.parent !== slides) { if (node instanceof Y.XmlFragment || node instanceof Y.XmlText) isText = true node = node.parent } if (!node) continue const id = getString(node, 'id') if (!id) continue if (isText) { text.add(id); continue } // The event landed on the slide map itself. Its `order` key is the // deck's order; a block's `order` key is not, and reaches here as // an event further down, so keys is null for it. const keys = node === e.target ? e.keysChanged : null if (keys && keys.has('order')) { order = true // A renumbering that touched nothing else has not changed what // the slide looks like, so the strip re-syncs and the stage is // left alone. if (keys.size === 1) continue } structure.add(id) } return { text: [...text], structure: [...structure], order } }