y-mxgraph 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/binding/index.d.ts +4 -0
- package/binding/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/y-mxgraph.cjs.js +31 -3
- package/y-mxgraph.cjs.js.map +1 -1
- package/y-mxgraph.es.js +31 -3
- package/y-mxgraph.es.js.map +1 -1
- package/y-mxgraph.iife.js +31 -3
- package/y-mxgraph.iife.js.map +1 -1
- package/y-mxgraph.umd.js +31 -3
- package/y-mxgraph.umd.js.map +1 -1
package/y-mxgraph.iife.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"y-mxgraph.iife.js","sources":["../src/helper/xml.ts","../src/models/mxCell.ts","../src/models/mxGraphModel.ts","../src/models/diagram.ts","../src/models/mxfile.ts","../src/binding/patch.ts","../src/transformer/index.ts","../src/helper/origin.ts","../src/binding/undoManager.ts","../src/helper/awarenessStateValue.ts","../src/helper/random.ts","../src/helper/cursor.ts","../src/binding/collaborator/cursor.ts","../src/helper/getId.ts","../src/binding/collaborator/selection.ts","../src/binding/collaborator/index.ts","../src/binding/index.ts"],"sourcesContent":["import { xml2js, js2xml, type ElementCompact } from \"xml-js\";\n\nfunction deepProcess(node: unknown): void {\n if (node == null) return;\n\n if (Array.isArray(node)) {\n for (const item of node) {\n deepProcess(item);\n }\n return;\n }\n\n if (typeof node !== \"object\") return;\n\n const obj = node as Record<string, unknown>;\n const keys = Object.keys(obj);\n for (const key of keys) {\n if (key === \"_attributes\") continue;\n\n let value = obj[key];\n const keyLower = key.toLowerCase();\n\n if (\n (keyLower === \"diagram\" || keyLower === \"mxcell\") &&\n value !== undefined &&\n !Array.isArray(value)\n ) {\n obj[key] = [value];\n value = obj[key];\n }\n\n if (Array.isArray(value)) {\n for (const v of value) deepProcess(v);\n } else if (value && typeof value === \"object\") {\n deepProcess(value);\n }\n }\n}\n\nexport function parse(xml: string) {\n const result = xml2js(xml, { compact: true }) as Record<string, unknown>;\n deepProcess(result);\n return result;\n}\n\nexport function serializer(obj: ElementCompact, spaces = 2) {\n return js2xml(obj, {\n compact: true,\n spaces,\n });\n}\n","import * as Y from \"yjs\";\nimport { xml2js, js2xml } from \"xml-js\";\nimport type { ElementCompact } from \"xml-js\";\n\nexport const key = \"mxCell\";\n\nconst mxGeometryKey = \"mxGeometry\";\nconst mxGeometryAttributeKey = \"geometry\";\n\nexport interface MxCellModel extends ElementCompact {\n [mxGeometryKey]?: ElementCompact;\n}\n\nexport function parse(object: MxCellModel): Y.XmlElement {\n const xmlElement = new Y.XmlElement(\"mxCell\");\n\n for (const attribute of Object.keys(object._attributes || {})) {\n xmlElement.setAttribute(\n attribute,\n `${object._attributes?.[attribute] || \"\"}`\n );\n }\n\n if (object[mxGeometryKey]) {\n const geometry = object[mxGeometryKey];\n const geometryString = js2xml(geometry, {\n compact: true,\n });\n xmlElement.setAttribute(mxGeometryAttributeKey, geometryString);\n delete object[mxGeometryKey];\n }\n\n return xmlElement;\n}\n\nexport function serialize(xmlElement: Y.XmlElement) {\n const rawAttributes = {\n ...xmlElement.getAttributes(),\n };\n\n // 提取 mxGeometry(不需要转义,它本身就是 XML 字符串)\n let mxGeometry: ElementCompact | null = null;\n let mxGeometryString: string | undefined;\n\n if (mxGeometryAttributeKey in rawAttributes) {\n mxGeometryString = rawAttributes[mxGeometryAttributeKey];\n delete rawAttributes[mxGeometryAttributeKey];\n }\n\n // 转义其他属性值中的特殊字符\n const attributes: Record<string, string> = {};\n for (const [key, value] of Object.entries(rawAttributes)) {\n if (typeof value === 'string') {\n attributes[key] = value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n } else if (value != null) {\n attributes[key] = String(value);\n }\n }\n\n // 解析 mxGeometry\n if (mxGeometryString) {\n try {\n const parsed = xml2js(mxGeometryString, { compact: true }) as Record<string, ElementCompact>;\n mxGeometry = parsed[mxGeometryKey] ?? null;\n if (mxGeometry && mxGeometry._attributes) {\n mxGeometry._attributes[\"as\"] = \"geometry\";\n }\n } catch (e) {\n console.warn(\"[y-mxgraph] Failed to parse mxGeometry:\", e);\n }\n }\n\n const obj: Record<string, unknown> = {\n _attributes: attributes,\n };\n\n if (mxGeometry) {\n obj[mxGeometryKey] = mxGeometry;\n }\n\n return obj;\n}\n","import * as Y from \"yjs\";\n\nimport {\n key as mxCellKey,\n parse as parseMxCell,\n serialize as serializeMxCell,\n type MxCellModel,\n} from \"./mxCell\";\nimport type { ElementCompact } from \"xml-js\";\n\nexport const key = \"mxGraphModel\";\nexport const mxCellOrderKey = mxCellKey + \"Order\";\n\nexport interface MxGraphModel extends ElementCompact {\n root: {\n mxCell: MxCellModel[];\n };\n}\n\nexport type YMxGraphModel = Y.Map<unknown>;\n\nexport function parse(object: MxGraphModel, doc?: Y.Doc) {\n const mxCells = (object.root[mxCellKey] || []).map((cell: MxCellModel) => {\n return {\n value: parseMxCell(cell),\n id: (cell._attributes?.id || \"\") as string,\n };\n });\n\n const mxGraphElement = doc?.getMap(key) || new Y.Map();\n\n const cells = new Y.Map<Y.XmlElement>();\n const cellsOrder = new Y.Array<string>();\n\n mxCells.forEach((cell) => {\n cells.set(cell.id, cell.value);\n });\n\n cellsOrder.push(mxCells.map((cell) => cell.id));\n\n mxGraphElement.set(mxCellKey, cells);\n mxGraphElement.set(mxCellOrderKey, cellsOrder);\n\n return mxGraphElement as YMxGraphModel;\n}\n\nexport function serialize(map: YMxGraphModel) {\n const cells = map.get(mxCellKey) as unknown as Y.Map<Y.XmlElement>;\n const cellsOrder = map.get(mxCellOrderKey) as unknown as Y.Array<string>;\n return {\n _attributes: {},\n root: {\n [mxCellKey]: cellsOrder\n .toArray()\n .map((id) => serializeMxCell(cells.get(id) as Y.XmlElement)),\n },\n };\n}\n","import * as Y from \"yjs\";\nimport {\n parse as parseMxGraphModel,\n serialize as serializeMxGraphModel,\n key as mxGraphModelKey,\n type MxGraphModel,\n type YMxGraphModel,\n} from \"./mxGraphModel\";\nimport type { ElementCompact } from \"xml-js\";\n\nexport const key = \"diagram\";\n\nexport interface Diagram extends ElementCompact {\n mxGraphModel: MxGraphModel;\n}\n\nexport type YDiagram = Y.Map<unknown>;\n\nexport function parse(object: Diagram): YDiagram {\n const yDiagramElement = new Y.Map();\n yDiagramElement.set(\"name\", `${object._attributes?.name || \"\"}`);\n yDiagramElement.set(\"id\", `${object._attributes?.id || \"\"}`);\n\n const mxGraphModel = parseMxGraphModel(object[mxGraphModelKey]);\n\n yDiagramElement.set(mxGraphModelKey, mxGraphModel);\n return yDiagramElement as YDiagram;\n}\n\nexport function serialize(yDiagram: YDiagram) {\n const mxGraphModel = yDiagram.get(mxGraphModelKey) as unknown as\n | YMxGraphModel\n | undefined;\n\n return {\n _attributes: {\n name: yDiagram.get(\"name\") as unknown as string,\n id: yDiagram.get(\"id\") as unknown as string,\n },\n [mxGraphModelKey]: mxGraphModel\n ? serializeMxGraphModel(mxGraphModel)\n : undefined,\n };\n}\n","import * as Y from \"yjs\";\nimport {\n parse as parseDiagram,\n key as diagramKey,\n serialize as serializeDiagram,\n} from \"./diagram\";\nimport type { Diagram, YDiagram } from \"./diagram\";\nimport type { ElementCompact } from \"xml-js\";\n\nexport const key = \"mxfile\";\nexport const diagramOrderKey = diagramKey + \"Order\";\n\nexport type YMxFile = Y.Map<unknown>;\n\nexport interface MxFile extends ElementCompact {\n diagram: Diagram[];\n}\n\nexport function parse(object: MxFile, doc: Y.Doc) {\n const mxfile = doc.getMap(key);\n mxfile.set(\"pages\", (object._attributes?.pages || \"1\") + \"\");\n\n const diagramList = object.diagram.map((diagram) => ({\n value: parseDiagram(diagram),\n id: (diagram._attributes?.id || \"\") as string,\n }));\n const diagramMap = new Y.Map<YDiagram>();\n const diagramOrder = new Y.Array<string>();\n diagramList.forEach((diagram) => {\n diagramMap.set(diagram.id, diagram.value);\n });\n diagramOrder.push(diagramList.map((diagram) => diagram.id));\n\n mxfile.set(diagramKey, diagramMap);\n mxfile.set(diagramOrderKey, diagramOrder);\n return mxfile;\n}\n\nexport function serializer(yMxFile: YMxFile): ElementCompact {\n const diagrams = yMxFile.get(diagramKey) as unknown as Y.Map<YDiagram>;\n const diagramOrder = yMxFile.get(\n diagramOrderKey,\n ) as unknown as Y.Array<string>;\n\n const orderIds = diagramOrder ? diagramOrder.toArray() : [];\n // 如果 diagramOrder 为空但 diagram map 不为空,使用 diagram map 中的所有 ID\n const ids = orderIds.length > 0 ? orderIds : (diagrams ? Array.from(diagrams.keys()) : []);\n\n const obj: Record<string, unknown> = {\n _attributes: {\n pages: (yMxFile.get(\"pages\") as string) || \"1\",\n },\n [diagramKey]: ids\n .map((id) => diagrams.get(id) as unknown as YDiagram)\n .filter((d): d is YDiagram => !!d)\n .map((diagramElement) => serializeDiagram(diagramElement)),\n };\n\n return obj as ElementCompact;\n}\n","import { parse, serializer as xmlSerializer } from \"../helper/xml\";\nimport {\n parse as parseDiagram,\n key as diagramKey,\n serialize as serializeDiagram,\n type YDiagram,\n} from \"../models/diagram\";\nimport {\n key as mxfileKey,\n type YMxFile,\n diagramOrderKey,\n} from \"../models/mxfile\";\nimport {\n mxCellOrderKey,\n key as mxGraphModelKey,\n type YMxGraphModel,\n} from \"../models/mxGraphModel\";\nimport { key as mxCellKey } from \"../models/mxCell\";\nimport * as Y from \"yjs\";\n\nconst DIFF_INSERT = \"i\";\nconst DIFF_REMOVE = \"r\";\nconst DIFF_UPDATE = \"u\";\n\ntype DocSnapshot = {\n diagramOrder: string[] | null;\n cellsOrder: Map<string, string[]>;\n cellAttrs: Map<string, Map<string, Record<string, string>>>;\n};\nconst docSnapshots = new WeakMap<Y.Doc, DocSnapshot>();\n\nfunction insertAfterUnique(\n orderArr: Y.Array<string>,\n id: string,\n previous: string | null | undefined,\n fallbackToEnd = false,\n) {\n const currentIds = orderArr.toArray();\n let anchorPos = previous ? currentIds.indexOf(previous) : -1;\n if (anchorPos === -1 && fallbackToEnd) anchorPos = currentIds.length - 1;\n let targetIndex = anchorPos + 1;\n\n const existingIndex = currentIds.indexOf(id);\n if (existingIndex === -1) {\n orderArr.insert(targetIndex, [id]);\n return;\n }\n\n if (existingIndex === targetIndex) return;\n\n if (existingIndex < targetIndex) targetIndex -= 1;\n orderArr.delete(existingIndex, 1);\n orderArr.insert(targetIndex, [id]);\n}\n\nfunction ensureUniqueOrder(orderArr: Y.Array<string>) {\n const arr = orderArr.toArray();\n const seen = new Set<string>();\n const dupIdx: number[] = [];\n for (let i = 0; i < arr.length; i++) {\n const id = arr[i];\n if (!id) continue;\n if (seen.has(id)) dupIdx.push(i);\n else seen.add(id);\n }\n if (dupIdx.length) {\n dupIdx.sort((a, b) => b - a).forEach((idx) => orderArr.delete(idx, 1));\n }\n}\n\nexport interface DiagramInsert {\n data: string;\n id: string;\n previous: string;\n}\n\nexport interface FilePatch {\n [DIFF_REMOVE]?: string[];\n [DIFF_INSERT]?: DiagramInsert[];\n [DIFF_UPDATE]?: {\n [key: string]: {\n name?: string;\n previous?: string;\n cells?: {\n [DIFF_REMOVE]?: string[];\n [DIFF_INSERT]?: Record<string, string>[];\n [DIFF_UPDATE]?: {\n [key: string]: Record<string, string>;\n };\n };\n };\n };\n}\n\nexport function applyFilePatch(\n doc: Y.Doc,\n patch: FilePatch,\n options?: { origin?: unknown },\n) {\n doc.transact(() => {\n const mxfile = doc.getMap(mxfileKey) as YMxFile;\n if (patch[DIFF_REMOVE]) {\n const diagramsMap = mxfile.get(diagramKey) as unknown as Y.Map<YDiagram>;\n const orderArr = mxfile.get(\n diagramOrderKey,\n ) as unknown as Y.Array<string>;\n ensureUniqueOrder(orderArr);\n const orderList = orderArr.toArray();\n\n const removeIds = patch[DIFF_REMOVE];\n if (removeIds && removeIds.length) {\n const indexList = removeIds\n .map((id) => orderList.indexOf(id))\n .filter((i) => i !== -1)\n .sort((a, b) => b - a);\n\n indexList.forEach((idx) => orderArr.delete(idx, 1));\n removeIds.forEach((id) => diagramsMap.delete(id));\n }\n }\n\n if (patch[DIFF_INSERT]) {\n const diagramsMap = mxfile.get(diagramKey) as unknown as Y.Map<YDiagram>;\n const orderArr = mxfile.get(\n diagramOrderKey,\n ) as unknown as Y.Array<string>;\n ensureUniqueOrder(orderArr);\n \n // 确保 diagramOrder 包含所有 diagram map 中的 IDs\n const currentOrder = orderArr.toArray();\n if (currentOrder.length === 0 && diagramsMap && diagramsMap.size > 0) {\n const allIds = Array.from(diagramsMap.keys());\n orderArr.push(allIds);\n }\n ensureUniqueOrder(orderArr);\n \n const existingIds = orderArr.toArray();\n const existingIndex = new Map<string, number>();\n existingIds.forEach((id, idx) => existingIndex.set(id, idx));\n\n const inserts = patch[DIFF_INSERT].map((item, order) => {\n const object = parse(item.data) as Record<string, unknown>;\n const diagramObj = Array.isArray(object?.diagram)\n ? (object.diagram as unknown[])[0]\n : object?.diagram;\n const diagramElement = parseDiagram(\n diagramObj as import(\"../models/diagram\").Diagram,\n );\n return {\n id: item.id,\n previous: item.previous || \"\",\n diagramElement,\n order,\n };\n });\n\n const byId = new Map(inserts.map((i) => [i.id, i] as const));\n const computeAnchor = (node: {\n id: string;\n previous: string;\n }): {\n anchorId: string;\n depth: number;\n } => {\n let depth = 1;\n let anchorId = \"\";\n let prevId = node.previous;\n const seen = new Set<string>([node.id]);\n while (prevId) {\n if (seen.has(prevId)) {\n depth = 1;\n anchorId = \"\";\n break;\n }\n seen.add(prevId);\n\n const prevNode = byId.get(prevId);\n if (prevNode) {\n depth += 1;\n prevId = prevNode.previous;\n continue;\n }\n\n if (existingIndex.has(prevId)) {\n anchorId = prevId;\n } else {\n anchorId = \"\";\n }\n break;\n }\n return { anchorId, depth };\n };\n\n const enriched = inserts.map((i) => ({ ...i, ...computeAnchor(i) }));\n\n enriched.sort((a, b) => {\n const aIdx = a.anchorId ? existingIndex.get(a.anchorId)! : -1;\n const bIdx = b.anchorId ? existingIndex.get(b.anchorId)! : -1;\n if (aIdx !== bIdx) return aIdx - bIdx;\n if (a.depth !== b.depth) return b.depth - a.depth;\n return b.order - a.order;\n });\n\n for (const item of enriched) {\n diagramsMap.set(item.id, item.diagramElement);\n insertAfterUnique(orderArr, item.id, item.anchorId || null);\n }\n }\n\n if (patch[DIFF_UPDATE]) {\n Object.keys(patch[DIFF_UPDATE]).forEach((id) => {\n const diagramsMap = mxfile.get(\n diagramKey,\n ) as unknown as Y.Map<YDiagram>;\n const diagram = diagramsMap.get(id) as YDiagram | undefined;\n if (diagram) {\n const update = patch[DIFF_UPDATE]![id];\n if (\"name\" in update) {\n (diagram as unknown as Y.Map<unknown>).set(\n \"name\",\n update.name || \"\",\n );\n }\n\n if (update.cells) {\n const yMxGraphModel = diagram.get(mxGraphModelKey) as\n | YMxGraphModel\n | undefined;\n if (!yMxGraphModel) return;\n const cellsMap = yMxGraphModel.get(mxCellKey) as\n | Y.Map<Y.XmlElement>\n | undefined;\n const orderArr = yMxGraphModel.get(mxCellOrderKey) as\n | Y.Array<string>\n | undefined;\n if (!cellsMap || !orderArr) return;\n ensureUniqueOrder(orderArr as Y.Array<string>);\n\n if (update.cells[DIFF_REMOVE] && update.cells[DIFF_REMOVE].length) {\n const orderIds = orderArr.toArray();\n const removeIndexList = update.cells[DIFF_REMOVE].map((cid) =>\n orderIds.indexOf(cid),\n )\n .filter((i) => i !== -1)\n .sort((a, b) => b - a);\n removeIndexList.forEach((idx) => orderArr.delete(idx, 1));\n update.cells[DIFF_REMOVE].forEach((cid) => cellsMap.delete(cid));\n }\n\n if (update.cells[DIFF_INSERT] && update.cells[DIFF_INSERT].length) {\n for (const item of update.cells[DIFF_INSERT]) {\n const id = item[\"id\"] as string | undefined;\n if (!id) continue;\n const xmlElement = new Y.XmlElement(\"mxCell\");\n Object.keys(item).forEach((key) => {\n if (key === \"previous\") return;\n xmlElement.setAttribute(key, item[key]);\n });\n cellsMap.set(id, xmlElement);\n const previous = item[\"previous\"] as string | undefined;\n const parent = item[\"parent\"] as string | undefined;\n let anchorId: string | null | undefined = null;\n let fallbackToEnd = true;\n if (typeof previous !== \"undefined\") {\n if (previous === \"\") {\n if (parent) {\n anchorId = parent;\n fallbackToEnd = true;\n } else {\n anchorId = null;\n fallbackToEnd = false;\n }\n } else {\n anchorId = previous;\n fallbackToEnd = true;\n }\n } else if (parent) {\n anchorId = parent;\n fallbackToEnd = true;\n }\n\n insertAfterUnique(\n orderArr as Y.Array<string>,\n id,\n anchorId,\n fallbackToEnd,\n );\n }\n }\n\n if (update.cells[DIFF_UPDATE]) {\n Object.keys(update.cells[DIFF_UPDATE]).forEach((cid) => {\n const updateObj = update.cells![DIFF_UPDATE]![cid];\n const cell = cellsMap.get(cid) as Y.XmlElement | undefined;\n if (cell) {\n Object.keys(updateObj).forEach((k) => {\n if (k === \"previous\") return;\n cell.setAttribute(k, updateObj[k]);\n });\n }\n });\n\n Object.keys(update.cells[DIFF_UPDATE]).forEach((cellId) => {\n const updateObj = update.cells![DIFF_UPDATE]![cellId];\n const hasPrev = \"previous\" in updateObj;\n const hasParent = \"parent\" in updateObj;\n if (!hasPrev && !hasParent) return;\n\n const prevVal = hasPrev\n ? (updateObj.previous as string)\n : undefined;\n const parentVal = hasParent\n ? (updateObj.parent as string)\n : undefined;\n\n let anchorId: string | null | undefined = null;\n let fallbackToEnd = true;\n\n if (hasPrev) {\n if (prevVal === \"\") {\n if (parentVal) {\n anchorId = parentVal;\n fallbackToEnd = true;\n } else {\n anchorId = null;\n fallbackToEnd = false;\n }\n } else {\n anchorId = prevVal;\n fallbackToEnd = true;\n }\n } else if (parentVal) {\n anchorId = parentVal;\n fallbackToEnd = true;\n }\n\n const currentIds = orderArr.toArray();\n const currentIndex = currentIds.indexOf(cellId);\n\n if (currentIndex === -1) {\n let newCell = cellsMap.get(cellId) as\n | Y.XmlElement\n | undefined;\n if (!newCell) {\n newCell = new Y.XmlElement(\"mxCell\");\n newCell.setAttribute(\"id\", cellId);\n Object.keys(updateObj).forEach((k) => {\n if (k === \"previous\") return;\n newCell!.setAttribute(k, updateObj[k] as string);\n });\n cellsMap.set(cellId, newCell);\n }\n insertAfterUnique(\n orderArr as Y.Array<string>,\n cellId,\n anchorId,\n fallbackToEnd,\n );\n return;\n }\n\n insertAfterUnique(\n orderArr as Y.Array<string>,\n cellId,\n anchorId,\n fallbackToEnd,\n );\n });\n }\n }\n\n if (\"previous\" in update) {\n const previous = update.previous || null;\n const orderArr = mxfile.get(\n diagramOrderKey,\n ) as unknown as Y.Array<string>;\n ensureUniqueOrder(orderArr);\n insertAfterUnique(orderArr, id, previous, false);\n }\n }\n });\n }\n }, options?.origin);\n}\n\nexport function initDocSnapshot(doc: Y.Doc, resetSnapshot = false) {\n try {\n const mxfile = doc.getMap(mxfileKey) as YMxFile;\n const diagramsMap = mxfile.get(diagramKey) as unknown as Y.Map<YDiagram>;\n const orderArr = mxfile.get(diagramOrderKey) as unknown as Y.Array<string>;\n \n // 如果 diagramOrder 为空但 diagram map 不为空,使用 diagram map 中的所有 ID\n const orderIds = orderArr ? orderArr.toArray() : [];\n const allDiagramIds = orderIds.length > 0 \n ? orderIds \n : (diagramsMap ? Array.from(diagramsMap.keys()) : []);\n \n // resetSnapshot=true 时把 diagramOrder 设为空数组,\n // 使第一次 generatePatch 把所有现有 diagram/cells 都识别为 insert\n const diagramOrder = resetSnapshot ? [] : allDiagramIds.slice();\n\n const snap: DocSnapshot = {\n diagramOrder,\n cellsOrder: new Map<string, string[]>(),\n cellAttrs: new Map<string, Map<string, Record<string, string>>>(),\n };\n\n const diagrams: YDiagram[] = diagramOrder\n .map((id) => diagramsMap.get(id) as YDiagram | undefined)\n .filter((d): d is YDiagram => !!d);\n for (const d of diagrams) {\n const did = (d.get(\"id\") as unknown as string) || \"\";\n if (!did) continue;\n const gm = d.get(mxGraphModelKey) as YMxGraphModel | undefined;\n if (gm) {\n const order = gm.get(mxCellOrderKey) as Y.Array<string> | undefined;\n const ids = order ? order.toArray().slice() : [];\n snap.cellsOrder.set(did, ids);\n const cellsMap = gm.get(mxCellKey) as Y.Map<Y.XmlElement> | undefined;\n const attrMap = new Map<string, Record<string, string>>();\n if (cellsMap) {\n for (const cid of ids) {\n const el = cellsMap.get(cid) as Y.XmlElement | undefined;\n if (el) {\n attrMap.set(\n cid,\n (el.getAttributes() as Record<string, string>) || {},\n );\n }\n }\n }\n snap.cellAttrs.set(did, attrMap);\n } else {\n snap.cellsOrder.set(did, []);\n snap.cellAttrs.set(did, new Map());\n }\n }\n\n docSnapshots.set(doc, snap);\n } catch (e) {\n console.warn(\"[y-mxgraph] initDocSnapshot failed:\", e);\n }\n}\n\nexport function generatePatch(\n events: Y.YEvent<\n Y.XmlElement | Y.Array<string> | Y.Map<Y.XmlElement> | YMxFile | YDiagram\n >[],\n explicitDoc?: Y.Doc,\n): FilePatch {\n const patch: FilePatch = {};\n\n const doc =\n explicitDoc ??\n (events[0] as unknown as { transaction?: { doc?: Y.Doc } } | undefined)\n ?.transaction?.doc;\n if (!doc) return patch;\n if (!explicitDoc && (!events || events.length === 0)) return patch;\n const mxfile = doc.getMap(mxfileKey) as YMxFile;\n const diagramsMap = mxfile.get(diagramKey) as unknown as Y.Map<YDiagram>;\n const orderArr = mxfile.get(diagramOrderKey) as unknown as Y.Array<string>;\n\n let snap = docSnapshots.get(doc);\n if (!snap) {\n snap = {\n diagramOrder: null,\n cellsOrder: new Map<string, string[]>(),\n cellAttrs: new Map<string, Map<string, Record<string, string>>>(),\n };\n docSnapshots.set(doc, snap);\n }\n const prevDiagramOrder = snap.diagramOrder;\n const prevCellsOrder = snap.cellsOrder;\n const prevCellsAttrs = snap.cellAttrs;\n\n const ensureUpdate = (diagramId: string) => {\n patch[DIFF_UPDATE] = patch[DIFF_UPDATE] || {};\n patch[DIFF_UPDATE]![diagramId] = patch[DIFF_UPDATE]![diagramId] || {};\n return patch[DIFF_UPDATE]![diagramId]!;\n };\n const ensureCellSection = (diagramId: string) => {\n const u = ensureUpdate(diagramId);\n u.cells = u.cells || {};\n return u.cells!;\n };\n\n // 如果 diagramOrder 为空但 diagram map 不为空,使用 diagram map 中的所有 ID\n const orderIds = orderArr.toArray();\n const currDiagramOrder = orderIds.length > 0 \n ? orderIds \n : (diagramsMap ? Array.from(diagramsMap.keys()) : []);\n const diagramsList = currDiagramOrder\n .map((id) => diagramsMap.get(id) as YDiagram | undefined)\n .filter((d): d is YDiagram => !!d);\n const currCellsOrder = new Map<string, string[]>();\n const cellAttrMap = new Map<string, Map<string, Record<string, string>>>();\n\n for (const d of diagramsList) {\n const did = (d.get(\"id\") as unknown as string) || \"\";\n const attrs = new Map<string, Record<string, string>>();\n const gm = d.get(mxGraphModelKey) as YMxGraphModel | undefined;\n if (gm) {\n const cellsMap = gm.get(mxCellKey) as Y.Map<Y.XmlElement> | undefined;\n const orderArr = gm.get(mxCellOrderKey) as Y.Array<string> | undefined;\n if (cellsMap && orderArr) {\n const ids = orderArr.toArray();\n currCellsOrder.set(did, ids);\n for (const cid of ids) {\n const c = cellsMap.get(cid) as Y.XmlElement | undefined;\n if (c)\n attrs.set(cid, (c.getAttributes() as Record<string, string>) || {});\n }\n } else {\n currCellsOrder.set(did, []);\n }\n } else {\n currCellsOrder.set(did, []);\n }\n cellAttrMap.set(did, attrs);\n }\n\n const insertedDiagramIdGlobal = new Set<string>();\n const insertedCellIdGlobal = new Set<string>();\n\n if (prevDiagramOrder) {\n const prevSet = new Set(prevDiagramOrder);\n const currSet = new Set(currDiagramOrder);\n\n const removed = prevDiagramOrder.filter(\n (id: string) => !currSet.has(id) && id,\n );\n if (removed.length) patch[DIFF_REMOVE] = removed;\n const removedDiagramSet = new Set(removed);\n\n const inserted = currDiagramOrder.filter(\n (id: string) => !prevSet.has(id) && id,\n );\n if (inserted.length) {\n patch[DIFF_INSERT] = patch[DIFF_INSERT] || [];\n for (const id of inserted) {\n const index = currDiagramOrder.indexOf(id);\n const previous = index <= 0 ? \"\" : currDiagramOrder[index - 1];\n const yDiagram = diagramsMap.get(id) as YDiagram | undefined;\n if (!yDiagram) continue;\n const data = xmlSerializer({ diagram: serializeDiagram(yDiagram) });\n patch[DIFF_INSERT]!.push({ id, previous, data });\n insertedDiagramIdGlobal.add(id);\n }\n }\n\n const prevNeighbor = (order: string[], id: string) => {\n const i = order.indexOf(id);\n return i <= 0 ? \"\" : order[i - 1];\n };\n const common = currDiagramOrder.filter((id) => prevSet.has(id) && id);\n for (const id of common) {\n const prevP = prevNeighbor(prevDiagramOrder, id);\n const currP = prevNeighbor(currDiagramOrder, id);\n if (prevP !== currP) {\n if (prevP && removedDiagramSet.has(prevP)) continue;\n const u = ensureUpdate(id);\n u.previous = currP;\n }\n }\n }\n\n const allDiagramIds = new Set<string>([\n ...(prevDiagramOrder || []),\n ...currDiagramOrder,\n ]);\n for (const did of allDiagramIds) {\n if (!did) continue;\n const prevCells = prevCellsOrder.get(did) || [];\n const currCells = currCellsOrder.get(did) || [];\n if (!prevCells.length && !currCells.length) continue;\n\n const prevSet = new Set(prevCells);\n const currSet = new Set(currCells);\n\n const removed = prevCells.filter((cid: string) => !currSet.has(cid) && cid);\n if (removed.length) {\n const cells = ensureCellSection(did);\n cells[DIFF_REMOVE] = (cells[DIFF_REMOVE] || []).concat(removed);\n }\n const removedCellSet = new Set(removed);\n\n const inserted = currCells.filter(\n (cid: string) => !prevSet.has(cid) && cid,\n );\n if (inserted.length) {\n const cells = ensureCellSection(did);\n cells[DIFF_INSERT] = cells[DIFF_INSERT] || [];\n const attrsMap = cellAttrMap.get(did) || new Map();\n for (const cid of inserted) {\n const attrs = attrsMap.get(cid) || {};\n const index = currCells.indexOf(cid);\n const previous = index <= 0 ? \"\" : currCells[index - 1];\n cells[DIFF_INSERT]!.push({\n ...(attrs as Record<string, string>),\n previous,\n });\n insertedCellIdGlobal.add(cid);\n }\n }\n\n const prevNeighbor = (order: string[], id: string) => {\n const i = order.indexOf(id);\n return i <= 0 ? \"\" : order[i - 1];\n };\n const commonCells = currCells.filter((cid) => prevSet.has(cid) && cid);\n for (const cid of commonCells) {\n const prevP = prevNeighbor(prevCells, cid);\n const currP = prevNeighbor(currCells, cid);\n if (prevP !== currP) {\n if (prevP && removedCellSet.has(prevP)) continue;\n const cells = ensureCellSection(did);\n cells[DIFF_UPDATE] = cells[DIFF_UPDATE] || {};\n const cellUpdate = (cells[DIFF_UPDATE]![cid] =\n cells[DIFF_UPDATE]![cid] || {});\n (cellUpdate as Record<string, unknown>).previous = currP;\n }\n }\n }\n\n {\n const diagramSet = new Set<Y.Map<unknown>>(\n diagramsList as unknown as Y.Map<unknown>[],\n );\n for (const ev of events) {\n const target = (ev as unknown as { target?: unknown }).target;\n if (!(target instanceof Y.Map)) continue;\n if (!diagramSet.has(target)) continue;\n const changed: Set<string> =\n (ev as unknown as { keysChanged?: Set<string> }).keysChanged ||\n new Set();\n if (!changed || !changed.has(\"name\")) continue;\n const did = (target.get(\"id\") as unknown as string) || \"\";\n if (!did || insertedDiagramIdGlobal.has(did)) continue;\n const u = ensureUpdate(did);\n u.name = (target.get(\"name\") as unknown as string) || \"\";\n }\n }\n\n if (!prevDiagramOrder) {\n for (const d of diagramsList) {\n const did = (d.get(\"id\") as unknown as string) || \"\";\n if (!did) continue;\n const u = ensureUpdate(did);\n u.name = (d.get(\"name\") as unknown as string) || \"\";\n }\n }\n\n for (const ev of events) {\n const target = (ev as unknown as { target?: unknown }).target;\n if (!(target instanceof Y.XmlElement)) continue;\n const el = target as Y.XmlElement;\n if (el.nodeName !== \"mxCell\") continue;\n\n const changed: Set<string> =\n (ev as unknown as { attributesChanged?: Set<string> })\n .attributesChanged ||\n (ev as unknown as { keysChanged?: Set<string> }).keysChanged ||\n new Set();\n if (!changed || (changed as Set<string>).size === 0) continue;\n\n const cellId = el.getAttribute(\"id\");\n if (!cellId || insertedCellIdGlobal.has(cellId)) continue;\n\n const idsEntries = Array.from(currCellsOrder.entries());\n let diagramId = \"\";\n for (const [did, ids] of idsEntries) {\n if (ids.includes(cellId)) {\n diagramId = did;\n break;\n }\n }\n if (!diagramId) continue;\n\n const cellsPatch = ensureCellSection(diagramId);\n cellsPatch[DIFF_UPDATE] = cellsPatch[DIFF_UPDATE] || {};\n const cellUpdate = (cellsPatch[DIFF_UPDATE]![cellId] =\n cellsPatch[DIFF_UPDATE]![cellId] || {});\n for (const key of Array.from(changed)) {\n cellUpdate[key] = el.getAttribute(key) || \"\";\n }\n }\n\n if (prevDiagramOrder) {\n for (const [did, currAttrsMap] of cellAttrMap.entries()) {\n const prevAttrsMap =\n prevCellsAttrs.get(did) || new Map<string, Record<string, string>>();\n const cellsPatch = ensureCellSection(did);\n cellsPatch[DIFF_UPDATE] = cellsPatch[DIFF_UPDATE] || {};\n const updateBucket = cellsPatch[DIFF_UPDATE]!;\n\n const currCells = currAttrsMap.keys();\n for (const cid of currCells) {\n if (insertedCellIdGlobal.has(cid)) continue;\n const prevAttrs = prevAttrsMap.get(cid) || {};\n const currAttrs = currAttrsMap.get(cid) || {};\n const keys = new Set<string>([\n ...Object.keys(prevAttrs),\n ...Object.keys(currAttrs),\n ]);\n const cellUpdate = (updateBucket[cid] = updateBucket[cid] || {});\n let changed = false;\n for (const k of keys) {\n const pv = prevAttrs[k] ?? \"\";\n const cv = currAttrs[k] ?? \"\";\n if (pv !== cv) {\n cellUpdate[k] = cv;\n changed = true;\n }\n }\n if (!changed) {\n if (Object.keys(cellUpdate).length === 0) {\n delete updateBucket[cid];\n }\n }\n }\n }\n }\n\n snap.diagramOrder = currDiagramOrder.slice();\n const newCellsOrder = new Map<string, string[]>();\n const newCellsAttrs = new Map<string, Map<string, Record<string, string>>>();\n for (const [did, arr] of currCellsOrder.entries()) {\n newCellsOrder.set(did, arr.slice());\n }\n for (const [did, attrsMap] of cellAttrMap.entries()) {\n const copy = new Map<string, Record<string, string>>();\n for (const [cid, attrs] of attrsMap.entries()) {\n copy.set(cid, { ...attrs });\n }\n newCellsAttrs.set(did, copy);\n }\n snap.cellsOrder = newCellsOrder;\n snap.cellAttrs = newCellsAttrs;\n docSnapshots.set(doc, snap);\n\n return patch;\n}\n","import * as Y from \"yjs\";\nimport { parse, serializer } from \"../helper/xml\";\nimport {\n parse as parseMxFile,\n key as mxfileKey,\n serializer as serializerMxFile,\n type YMxFile,\n} from \"../models/mxfile\";\nimport {\n parse as parseMxGraphModel,\n key as mxGraphModelKey,\n serialize as serializerMxGraphModel,\n type YMxGraphModel,\n} from \"../models/mxGraphModel\";\n\nexport function xml2doc(xml: string, doc: Y.Doc): Y.Doc {\n const object = parse(xml);\n\n const mxfile = (object as Record<string, unknown>).mxfile;\n const mxGraphModel = (object as Record<string, unknown>).mxGraphModel;\n if (mxfile) {\n doc.transact(() => {\n parseMxFile(mxfile as import(\"../models/mxfile\").MxFile, doc);\n });\n } else if (mxGraphModel) {\n doc.transact(() => {\n parseMxGraphModel(mxGraphModel as import(\"../models/mxGraphModel\").MxGraphModel, doc);\n });\n } else {\n throw new Error(\"不支持的文件格式\");\n }\n\n return doc;\n}\n\nexport function doc2xml(doc: Y.Doc, spaces = 0): string {\n if (doc.share.has(mxfileKey)) {\n return serializer(\n {\n [mxfileKey]: serializerMxFile(\n doc.share.get(mxfileKey) as unknown as YMxFile,\n ),\n },\n spaces,\n );\n } else if (doc.share.has(mxGraphModelKey)) {\n return serializer(\n {\n [mxGraphModelKey]: serializerMxGraphModel(\n doc.share.get(mxGraphModelKey) as unknown as YMxGraphModel,\n ),\n },\n spaces,\n );\n }\n\n return \"\";\n}\n","/**\n * 本地修改事务的 origin 标记,供 UndoManager.trackedOrigins 使用。\n * 对外导出,外部创建 Y.UndoManager 时可将其加入 trackedOrigins,\n * 以确保只追踪 binding 内部产生的本地变更。\n */\nexport const LOCAL_ORIGIN: object = {};\n","/**\n * 绑定 Y.UndoManager 到 draw.io 的 editor.undoManager,提供 mxUndoManager 兼容层。\n * 仅在外部传入 undoManager 时调用。\n */\nimport * as Y from \"yjs\";\nimport { LOCAL_ORIGIN } from \"../helper/origin\";\nimport type { DrawioFile } from \"../types/drawio\";\n\ntype ListenerFn = (sender: unknown, evt?: unknown) => void;\n\nfunction createMxEventObject(name: string, props?: Record<string, unknown>) {\n const _props = props || {};\n return {\n name,\n getName: () => name,\n getProperty: (k: string) => _props[k],\n };\n}\n\nexport function bindUndoManager(doc: Y.Doc, file: DrawioFile, yUndo: Y.UndoManager) {\n const editor = file.getUi().editor;\n const originUndoManager = editor.undoManager;\n\n let lastTxnLocalOrigin = false;\n const beforeTxnHandler = (t: Y.Transaction) => {\n lastTxnLocalOrigin = !!(t.local || t.origin === LOCAL_ORIGIN);\n };\n const afterTxnHandler = (t: Y.Transaction) => {\n lastTxnLocalOrigin = !!(t.local || t.origin === LOCAL_ORIGIN);\n };\n doc.on(\"beforeTransaction\", beforeTxnHandler);\n doc.on(\"afterTransaction\", afterTxnHandler);\n\n const pairs: Array<[string, ListenerFn]> = [];\n const raw = Array.isArray(originUndoManager?.eventListeners)\n ? (originUndoManager.eventListeners as unknown[])\n : [];\n for (let i = 0; i + 1 < raw.length; i += 2) {\n const key = String(raw[i]);\n const fn = raw[i + 1] as ListenerFn;\n pairs.push([key, fn]);\n }\n\n const mxLike: Record<string, unknown> & {\n eventListeners: Array<string | ListenerFn>;\n history: unknown[];\n indexOfNextAdd: number;\n _y: Y.UndoManager;\n addListener(name: string, fn: ListenerFn): void;\n fireEvent(evt: unknown): void;\n clear(): void;\n canUndo(): boolean;\n canRedo(): boolean;\n undo(): void;\n redo(): void;\n undoableEditHappened(_edit: unknown): void;\n } = {\n eventListeners: [] as Array<string | ListenerFn>,\n history: [] as unknown[],\n indexOfNextAdd: 0,\n _y: yUndo,\n\n addListener(name: string, fn: ListenerFn) {\n this.eventListeners.push(name, fn);\n },\n\n fireEvent(evt: unknown) {\n const eventName: string =\n (evt as { name?: string } | undefined)?.name ||\n ((evt as { getName?: () => string } | undefined)?.getName?.() ?? \"\");\n for (let i = 0; i + 1 < this.eventListeners.length; i += 2) {\n const key = this.eventListeners[i];\n const listener = this.eventListeners[i + 1] as ListenerFn;\n if (key === eventName) {\n try {\n listener(this, evt);\n } catch (e) {\n console.warn(\"[y-mxgraph] undoManager event listener error:\", e);\n }\n }\n }\n },\n\n clear() {\n if (typeof this._y.clear === \"function\") {\n this._y.clear();\n } else {\n while (this._y.canUndo && this._y.canUndo()) this._y.undo();\n while (this._y.canRedo && this._y.canRedo()) this._y.redo();\n }\n this.history = [];\n this.indexOfNextAdd = 0;\n this.fireEvent(createMxEventObject(\"clear\"));\n },\n\n canUndo(): boolean {\n return typeof this._y.canUndo === \"function\" && this._y.canUndo();\n },\n\n canRedo(): boolean {\n return typeof this._y.canRedo === \"function\" && this._y.canRedo();\n },\n\n undo() {\n this._y.undo();\n },\n\n redo() {\n this._y.redo();\n },\n\n undoableEditHappened() {\n // no-op: 让 yjs 基于事务决定是否入栈\n },\n };\n\n type YUndoEventName = \"stack-item-added\" | \"stack-cleared\" | \"stack-item-popped\" | \"stack-item-updated\";\n const bridgeHandlers: Array<[YUndoEventName, () => void]> = [];\n const bridge = (mxEventName: \"add\" | \"clear\", yEventName: YUndoEventName) => {\n const handler = () => {\n if (mxEventName !== \"clear\" && !lastTxnLocalOrigin) {\n return;\n }\n switch (mxEventName) {\n case \"add\": {\n if (mxLike.indexOfNextAdd < mxLike.history.length) {\n mxLike.history.splice(\n mxLike.indexOfNextAdd,\n mxLike.history.length - mxLike.indexOfNextAdd,\n );\n }\n mxLike.history.push({});\n mxLike.indexOfNextAdd = mxLike.history.length;\n break;\n }\n case \"clear\": {\n mxLike.history = [];\n mxLike.indexOfNextAdd = 0;\n break;\n }\n }\n\n const evt = createMxEventObject(mxEventName, { edit: { changes: [] } });\n mxLike.fireEvent(evt);\n };\n yUndo.on(yEventName, handler);\n bridgeHandlers.push([yEventName, handler]);\n };\n\n bridge(\"add\", \"stack-item-added\");\n bridge(\"clear\", \"stack-cleared\");\n\n const poppedHandler = (e: { type?: string; reason?: string; kind?: string }) => {\n const t = e && (e.type || e.reason || e.kind);\n if (t === \"undo\") {\n if (mxLike.indexOfNextAdd > 0) mxLike.indexOfNextAdd--;\n const evt = createMxEventObject(\"undo\", { edit: { changes: [] } });\n mxLike.fireEvent(evt);\n } else if (t === \"redo\") {\n if (mxLike.indexOfNextAdd < mxLike.history.length)\n mxLike.indexOfNextAdd++;\n const evt = createMxEventObject(\"redo\", { edit: { changes: [] } });\n mxLike.fireEvent(evt);\n }\n };\n yUndo.on(\"stack-item-popped\", poppedHandler);\n\n const updatedHandler = () => {\n const evt = createMxEventObject(\"redo\", { edit: { changes: [] } });\n mxLike.fireEvent(evt);\n };\n yUndo.on(\"stack-item-updated\", updatedHandler);\n\n pairs.forEach(([key, fn]) => {\n const k = key.toLowerCase();\n if (k === \"add\" || k === \"clear\" || k === \"undo\" || k === \"redo\") {\n mxLike.addListener(k, fn);\n }\n });\n\n editor.undoManager = mxLike;\n\n editor.undoListener = function () {\n // no-op in yjs mode\n };\n\n const destroy = () => {\n doc.off(\"beforeTransaction\", beforeTxnHandler);\n doc.off(\"afterTransaction\", afterTxnHandler);\n bridgeHandlers.forEach(([event, handler]) => {\n yUndo.off(event, handler);\n });\n yUndo.off(\"stack-item-popped\", poppedHandler);\n yUndo.off(\"stack-item-updated\", updatedHandler);\n // 恢复原始 undoManager\n editor.undoManager = originUndoManager;\n editor.undoListener = originUndoManager?.undoListener;\n };\n\n return destroy;\n}\n","import { type Awareness } from \"y-protocols/awareness\";\n\nexport function getAwarenessStateValue<T>(\n awareness: Awareness,\n key: string,\n clientId?: string | number\n): T | null {\n const states = awareness.getStates();\n const id = clientId != null ? Number(clientId) : awareness.clientID;\n const clientState = states.get(id as number);\n if (!clientState) return null;\n if (!key) return clientState as T;\n return getByPath(clientState, key) as T | null;\n}\n\nfunction getByPath(obj: unknown, path: string): unknown {\n const parts = path.split(\".\");\n let cur: unknown = obj;\n for (const part of parts) {\n if (cur == null) return null;\n const key: string | number =\n Array.isArray(cur) && /^\\d+$/.test(part) ? Number(part) : part;\n cur = (cur as Record<string, unknown>)?.[key];\n }\n return cur;\n}\n\nexport function setAwarenessStateValue(\n awareness: Awareness,\n key: string,\n value: unknown,\n clientId?: string | number\n): boolean {\n const id = clientId != null ? Number(clientId) : awareness.clientID;\n if (id !== awareness.clientID) return false;\n if (!key) {\n awareness.setLocalState(value as Record<string, unknown>);\n return true;\n }\n const current = (awareness.getLocalState() || {}) as Record<string, unknown>;\n const next = setByPath(current, key, value);\n awareness.setLocalState(next);\n return true;\n}\n\nfunction setByPath(obj: unknown, path: string, value: unknown): Record<string, unknown> {\n const parts = path.split(\".\");\n const root = Array.isArray(obj) ? obj.slice() : { ...(obj as Record<string, unknown>) };\n let cur: Record<string | number, unknown> = root as Record<string | number, unknown>;\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const isIndex = /^\\d+$/.test(part);\n const key: string | number = isIndex ? Number(part) : part;\n const isLast = i === parts.length - 1;\n if (isLast) {\n cur[key] = value;\n } else {\n let next = cur[key];\n const nextIsIndex = /^\\d+$/.test(parts[i + 1]);\n if (next == null) {\n next = nextIsIndex ? [] : {};\n } else {\n next = Array.isArray(next) ? next.slice() : { ...(next as Record<string, unknown>) };\n }\n cur[key] = next;\n cur = next as Record<string | number, unknown>;\n }\n }\n return root as Record<string, unknown>;\n}\n","export function generateColor(seed?: string | number) {\n const hash = hashString(String(seed || Math.random()));\n const h = hash % 360;\n const s = 65 + ((hash >>> 8) % 20);\n const l = 55 + ((hash >>> 16) % 10);\n return hslToHex(h, s, l);\n}\n\nexport function generateRandomName(): string {\n const len = 6;\n const alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let id = \"\";\n if (\n typeof crypto !== \"undefined\" &&\n typeof (crypto as Crypto).getRandomValues === \"function\"\n ) {\n const bytes = new Uint8Array(len);\n (crypto as Crypto).getRandomValues(bytes);\n for (let i = 0; i < len; i++) {\n id += alphabet[bytes[i] % alphabet.length];\n }\n } else {\n for (let i = 0; i < len; i++) {\n id += alphabet[Math.floor(Math.random() * alphabet.length)];\n }\n }\n return id;\n}\n\nexport function generateRandomId(): string {\n return generateRandomName();\n}\n\nfunction hashString(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n }\n return hash >>> 0;\n}\n\nfunction hslToHex(h: number, s: number, l: number): string {\n s /= 100;\n l /= 100;\n const c = (1 - Math.abs(2 * l - 1)) * s;\n const hp = h / 60;\n const x = c * (1 - Math.abs((hp % 2) - 1));\n let r1 = 0,\n g1 = 0,\n b1 = 0;\n if (hp >= 0 && hp < 1) [r1, g1, b1] = [c, x, 0];\n else if (hp >= 1 && hp < 2) [r1, g1, b1] = [x, c, 0];\n else if (hp >= 2 && hp < 3) [r1, g1, b1] = [0, c, x];\n else if (hp >= 3 && hp < 4) [r1, g1, b1] = [0, x, c];\n else if (hp >= 4 && hp < 5) [r1, g1, b1] = [x, 0, c];\n else [r1, g1, b1] = [c, 0, x];\n const m = l - c / 2;\n const r = Math.round((r1 + m) * 255);\n const g = Math.round((g1 + m) * 255);\n const b = Math.round((b1 + m) * 255);\n return \"#\" + [r, g, b].map((v) => v.toString(16).padStart(2, \"0\")).join(\"\");\n}\n","export function createCursorImage(color: string) {\n const w = 8;\n const h = 12;\n const path =\n '<path d=\"M 4 0 L 8 12 L 4 10 L 0 12 Z\" stroke=\"' +\n color +\n '\" fill=\"' +\n color +\n '\"/>';\n const svg =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"' +\n w +\n 'px\" height=\"' +\n h +\n 'px\" viewBox=\"0 0 ' +\n w +\n \" \" +\n h +\n '\" version=\"1.1\">' +\n path +\n \"</svg>\";\n const bytes = new Uint8Array(svg.length);\n for (let i = 0; i < svg.length; i++) {\n bytes[i] = svg.charCodeAt(i);\n }\n const encoded = btoa(String.fromCharCode.apply(null, bytes as unknown as number[]));\n return \"data:image/svg+xml;base64,\" + encoded;\n}\n","import { throttle } from \"lodash-es\";\nimport { colord } from \"colord\";\nimport { createCursorImage } from \"../../helper/cursor\";\n\nimport { type Awareness } from \"y-protocols/awareness\";\nimport { type RemoteCursor } from \"./index\";\nimport type { DrawioFile, MxGraph } from \"../../types/drawio\";\n\nexport const CacheKey = \"__remoteCursor__\";\n\nfunction createCursorEl(color: string, username: string) {\n const cursor = document.createElement(\"div\");\n cursor.style.position = \"absolute\";\n cursor.style.opacity = \"0.9\";\n cursor.style.transition = \"all 0.3s ease-in-out\";\n\n const img = document.createElement(\"img\");\n img.style.transform = \"rotate(-45deg) translateX(-14px)\";\n img.setAttribute(\"src\", createCursorImage(color));\n img.style.width = \"10px\";\n img.style.transition = \"all 0.3s ease-in-out\";\n cursor.appendChild(img);\n\n const name = document.createElement(\"div\");\n name.style.backgroundColor = color;\n name.style.color = colord(color).isDark() ? \"#fff\" : \"#000\";\n name.style.fontSize = \"9pt\";\n name.style.padding = \"3px 7px\";\n name.style.marginTop = \"8px\";\n name.style.borderRadius = \"10px\";\n name.style.maxWidth = \"100px\";\n name.style.overflow = \"hidden\";\n name.style.textOverflow = \"ellipsis\";\n name.style.whiteSpace = \"nowrap\";\n\n name.innerText = username;\n cursor.appendChild(name);\n return cursor;\n}\n\nexport function bindCursor(\n file: DrawioFile,\n options: {\n awareness: Awareness;\n graph?: MxGraph;\n mouseMoveThrottle?: number;\n },\n) {\n const graph = options.graph || file.getUi().editor.graph;\n const awareness = options.awareness;\n const mouseMoveThrottle = options.mouseMoveThrottle ?? 100;\n\n const listener = {\n startX: 0,\n startY: 0,\n scrollLeft: 0,\n scrollTop: 0,\n mouseDown: function () {},\n mouseUp: function () {},\n mouseMove: throttle(function (\n _sender: unknown,\n event: { graphX: number; graphY: number; evt: MouseEvent },\n ) {\n const containerRect = graph.container.getBoundingClientRect();\n const { translate, scale } = graph.view;\n\n const x = Math.round(\n (event.evt.clientX - containerRect.x + graph.container.scrollLeft) /\n scale -\n translate.x,\n );\n const y = Math.round(\n (event.evt.clientY - containerRect.y + graph.container.scrollTop) /\n scale -\n translate.y,\n );\n\n awareness.setLocalStateField(\"cursor\", {\n x,\n y,\n pageId: file.getUi().currentPage?.getId(),\n });\n }, mouseMoveThrottle),\n };\n\n graph.addMouseListener(listener);\n\n // 鼠标离开画布时隐藏光标\n const handleMouseLeave = () => {\n awareness.setLocalStateField(\"cursor\", {\n x: 0,\n y: 0,\n pageId: file.getUi().currentPage?.getId(),\n hide: true,\n });\n };\n graph.container.addEventListener(\"mouseleave\", handleMouseLeave);\n\n return () => {\n graph.removeMouseListener(listener);\n graph.container.removeEventListener(\"mouseleave\", handleMouseLeave);\n };\n}\n\nexport function renderRemoteCursors(\n ui: { editor: { graph: MxGraph }; currentPage?: { getId(): string } | null; diagramContainer: HTMLElement },\n remotes: Map<number, RemoteCursor>,\n) {\n if (!(CacheKey in ui)) {\n (ui as Record<string, unknown>)[CacheKey] = new Map<number, HTMLDivElement>();\n }\n\n const cache = (ui as Record<string, unknown>)[CacheKey] as Map<number, HTMLDivElement>;\n const currentPageId = ui.currentPage?.getId();\n\n if (!currentPageId) {\n Array.from(cache.values()).forEach((el) => el.remove());\n cache.clear();\n return;\n }\n\n const currentPageRemotes: RemoteCursor[] = [];\n const otherPageRemotes: RemoteCursor[] = [];\n const leaveRemotesIds = new Set<number>();\n\n Array.from(cache.keys()).forEach((clientId) => {\n if (!remotes.has(clientId)) leaveRemotesIds.add(clientId);\n });\n\n Array.from(remotes.values()).forEach((remote) => {\n if (remote.cursorState?.pageId === currentPageId) {\n currentPageRemotes.push(remote);\n } else {\n otherPageRemotes.push(remote);\n }\n });\n\n leaveRemotesIds.forEach((clientId) => {\n const el = cache.get(clientId);\n cache.delete(clientId);\n if (!el) return;\n el.remove();\n });\n\n otherPageRemotes.forEach(({ clientId }) => {\n const el = cache.get(clientId);\n if (!el) return;\n el.remove();\n });\n\n if (!currentPageRemotes.length) return;\n\n const graph = ui.editor.graph;\n const { translate, scale } = graph.view;\n\n currentPageRemotes.forEach(\n ({ clientId, cursorState, userColor, userName }) => {\n if (!cursorState) return;\n let el = cache.get(clientId);\n\n // 隐藏状态:移除光标元素\n if (cursorState.hide) {\n if (el) {\n el.remove();\n cache.delete(clientId);\n }\n return;\n }\n\n if (!el) {\n el = createCursorEl(userColor, userName);\n ui.diagramContainer.appendChild(el);\n cache.set(clientId, el);\n }\n\n const x = (translate.x + cursorState.x) * scale + 8;\n const y = (translate.y + cursorState.y) * scale - 12;\n\n const cx = Math.max(\n graph.container.scrollLeft,\n Math.min(\n graph.container.scrollLeft +\n graph.container.clientWidth -\n el.clientWidth,\n x,\n ),\n );\n\n const cy = Math.max(\n graph.container.scrollTop - 22,\n Math.min(\n graph.container.scrollTop +\n graph.container.clientHeight -\n el.clientHeight,\n y,\n ),\n );\n el.style.left = cx + \"px\";\n el.style.top = cy + \"px\";\n el.style.display = \"\";\n },\n );\n}\n","export function getId(item: { id?: string | number }) {\n if (item.id) return item.id;\n return null;\n}\n","import { type Awareness } from \"y-protocols/awareness\";\nimport { getId } from \"../../helper/getId\";\nimport { type RemoteCursor } from \"./index\";\nimport type { DrawioFile, MxGraph } from \"../../types/drawio\";\n\nexport const SELECTION_OPACITY = 70;\nexport const CacheKey = \"__remoteSelection__\";\n\nexport function bindSelection(\n file: DrawioFile,\n options: { awareness: Awareness; graph?: MxGraph },\n) {\n const graph = options.graph || file.getUi().editor.graph;\n const awareness = options.awareness;\n\n const handler = function () {\n const pageId = file.getUi().currentPage?.getId();\n const cells = graph.getSelectionModel().cells as Record<string, unknown>;\n const ids = Object.keys(cells || {})\n .map(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (key) => getId(cells[key] as any) as string,\n )\n .filter(Boolean);\n awareness.setLocalStateField(\"selection\", { ids, pageId });\n };\n\n const selectionModel = graph.getSelectionModel();\n selectionModel.addListener(\"change\", handler);\n\n return () => {\n selectionModel.removeListener(\"change\", handler);\n };\n}\n\nexport function renderRemoteSelections(\n ui: { editor: { graph: MxGraph }; currentPage?: { getId(): string } | null },\n remotes: Map<number, RemoteCursor>,\n) {\n if (!(CacheKey in ui)) {\n (ui as Record<string, unknown>)[CacheKey] = new Map<\n number,\n Map<string, { destroy: () => void }>\n >();\n }\n\n const cache = (ui as Record<string, unknown>)[CacheKey] as Map<\n number,\n Map<string, { destroy: () => void }>\n >;\n\n const currentPageId = ui.currentPage?.getId();\n\n if (!currentPageId) {\n cache.clear();\n return;\n }\n\n const currentPageRemotes: RemoteCursor[] = [];\n const otherPageRemotes: RemoteCursor[] = [];\n const leaveRemotesIds = new Set<number>();\n\n Array.from(cache.keys()).forEach((clientId) => {\n if (!remotes.has(clientId)) leaveRemotesIds.add(clientId);\n });\n\n Array.from(remotes.values()).forEach((remote) => {\n if (remote.selectionState?.pageId === currentPageId) {\n currentPageRemotes.push(remote);\n } else {\n otherPageRemotes.push(remote);\n }\n });\n\n leaveRemotesIds.forEach((clientId) => {\n const highlightCellMap = cache.get(clientId);\n cache.delete(clientId);\n if (!highlightCellMap) return;\n Array.from(highlightCellMap.values()).forEach((h) => h.destroy());\n highlightCellMap.clear();\n });\n\n otherPageRemotes.forEach(({ clientId }) => {\n const highlightCellMap = cache.get(clientId);\n if (!highlightCellMap) return;\n Array.from(highlightCellMap.values()).forEach((h) => h.destroy());\n highlightCellMap.clear();\n });\n\n if (!currentPageRemotes.length) return;\n\n const graph = ui.editor.graph;\n\n currentPageRemotes.forEach(({ clientId, selectionState, userColor }) => {\n let highlightCellMap = cache.get(clientId);\n if (!highlightCellMap) {\n highlightCellMap = new Map<string, { destroy: () => void }>();\n cache.set(clientId, highlightCellMap);\n }\n\n const currentIds = new Set<string>(selectionState?.ids ?? []);\n\n // 移除不再选中的高亮\n Array.from(highlightCellMap.keys()).forEach((id) => {\n if (!currentIds.has(id)) {\n highlightCellMap.get(id)?.destroy();\n highlightCellMap.delete(id);\n }\n });\n\n // 添加新选中的高亮\n currentIds.forEach((id) => {\n if (highlightCellMap.has(id)) return;\n const cell = graph.model.getCell(id);\n if (cell) {\n const highlightCell = graph.highlightCell(\n cell,\n userColor,\n 60000,\n SELECTION_OPACITY,\n 3,\n );\n highlightCellMap.set(id, highlightCell);\n }\n });\n });\n}\n","import { type Awareness } from \"y-protocols/awareness\";\nimport {\n getAwarenessStateValue,\n setAwarenessStateValue,\n} from \"../../helper/awarenessStateValue\";\nimport { generateColor, generateRandomName } from \"../../helper/random\";\nimport { bindCursor, renderRemoteCursors } from \"./cursor\";\nimport { bindSelection, renderRemoteSelections } from \"./selection\";\nimport type { DrawioFile, MxGraph } from \"../../types/drawio\";\n\nexport const DEFAULT_USER_NAME_KEY = \"user.name\";\nexport const DEFAULT_USER_COLOR_KEY = \"user.color\";\n\ntype CursorState = {\n x: number;\n y: number;\n pageId?: string | null;\n hide?: boolean;\n};\n\ntype SelectionState = {\n ids: string[];\n pageId?: string | null;\n};\n\nexport type RemoteCursor = {\n clientId: number;\n cursorState: CursorState | null;\n selectionState: SelectionState | null;\n userColor: string;\n userName: string;\n};\n\nexport function bindCollaborator(\n file: DrawioFile,\n options: {\n awareness: Awareness;\n graph?: MxGraph;\n cursor?: boolean | { userNameKey?: string; userColorKey?: string };\n mouseMoveThrottle?: number;\n },\n) {\n const graph = options.graph || file.getUi().editor.graph;\n const awareness = options.awareness;\n const mouseMoveThrottle = options.mouseMoveThrottle ?? 100;\n\n const cursorOption = options.cursor;\n const userNameKey =\n typeof cursorOption === \"object\" && cursorOption?.userNameKey\n ? cursorOption.userNameKey\n : DEFAULT_USER_NAME_KEY;\n const userColorKey =\n typeof cursorOption === \"object\" && cursorOption?.userColorKey\n ? cursorOption.userColorKey\n : DEFAULT_USER_COLOR_KEY;\n\n let userName = getAwarenessStateValue<string>(awareness, userNameKey);\n if (!userName) {\n userName = generateRandomName();\n setAwarenessStateValue(awareness, userNameKey, userName);\n }\n let userColor = getAwarenessStateValue<string>(awareness, userColorKey);\n if (!userColor) {\n userColor = generateColor(userName);\n setAwarenessStateValue(awareness, userColorKey, userColor);\n }\n\n const cleanupCursor = bindCursor(file, {\n awareness,\n graph,\n mouseMoveThrottle,\n });\n const cleanupSelection = bindSelection(file, {\n awareness,\n graph,\n });\n\n const showCursor = options.cursor ?? true;\n let cleanupAwareness: (() => void) | undefined;\n\n if (typeof showCursor === \"boolean\" && showCursor) {\n const awarenessHandler = (update: {\n added: number[];\n removed: number[];\n updated: number[];\n }) => {\n const states = awareness.getStates();\n const remotes = new Map<number, RemoteCursor>();\n\n const changedClientIds = new Set([...update.added, ...update.updated]);\n for (const [clientId] of states.entries()) {\n if (clientId === awareness.clientID) continue;\n if (!changedClientIds.has(clientId)) continue;\n\n const name =\n getAwarenessStateValue<string>(awareness, userNameKey, clientId) ||\n clientId + \"\";\n const color =\n getAwarenessStateValue<string>(awareness, userColorKey, clientId) ||\n \"#000000\";\n\n remotes.set(clientId, {\n clientId,\n cursorState: getAwarenessStateValue<CursorState>(\n awareness,\n \"cursor\",\n clientId,\n ),\n selectionState: getAwarenessStateValue<SelectionState>(\n awareness,\n \"selection\",\n clientId,\n ),\n userColor: color,\n userName: name,\n });\n }\n\n renderRemoteCursors(file.getUi(), remotes);\n renderRemoteSelections(file.getUi(), remotes);\n };\n awareness.on(\"update\", awarenessHandler);\n cleanupAwareness = () => awareness.off(\"update\", awarenessHandler);\n }\n\n return () => {\n cleanupCursor?.();\n cleanupSelection?.();\n cleanupAwareness?.();\n };\n}\n","import * as Y from \"yjs\";\nimport { type Awareness } from \"y-protocols/awareness\";\nimport { applyFilePatch, generatePatch, initDocSnapshot } from \"./patch\";\nimport { xml2doc, doc2xml } from \"../transformer\";\nimport { bindUndoManager } from \"./undoManager\";\nimport { bindCollaborator } from \"./collaborator\";\nimport { LOCAL_ORIGIN } from \"../helper/origin\";\nimport {\n key as mxfileKey,\n diagramOrderKey,\n type YMxFile,\n} from \"../models/mxfile\";\nimport {\n key as diagramKey,\n parse as parseDiagram,\n type YDiagram,\n} from \"../models/diagram\";\nimport { parse as parseXml } from \"../helper/xml\";\nimport type { DrawioFile, MxGraphModel } from \"../types/drawio\";\n\n/**\n * 控制 Binding 构造时 file 与 Y.Doc 的初始内容对齐策略。\n * - `replace` : doc 非空则用 doc 覆盖 file;doc 为空则保留 file 现有数据(默认)。\n * - `merge-remote` : 按 diagram id 取并集,同 id 冲突时以 doc 为准(远端权威)。\n * - `merge-client` : 按 diagram id 取并集,同 id 冲突时以 file 为准(本地权威,覆盖到 doc)。\n */\nexport type InitialContentStrategy =\n | \"replace\"\n | \"merge-remote\"\n | \"merge-client\";\n\nexport interface BindDrawioFileOptions {\n doc: Y.Doc;\n awareness?: Awareness;\n undoManager?: Y.UndoManager;\n mouseMoveThrottle?: number;\n cursor?:\n | boolean\n | {\n userNameKey?: string;\n userColorKey?: string;\n };\n /**\n * 初始内容对齐策略,默认 `replace`。详见 {@link InitialContentStrategy}。\n */\n initialContent?: InitialContentStrategy;\n /**\n * 自定义把 XML 应用到 file 的方式。默认实现只调用\n * `file.ui.setFileData(xml)`(刷新 UI / 重建 pages),\n * **不会**调用 `file.setData(xml)`,以避免把 file 标记为「已修改」\n * 触发 draw.io 的 \"Save diagrams to:\" 存储选择对话框。\n *\n * 若业务方确实需要同步 `file.data`(如自定义 CollabFile 或依赖\n * `file.save()`),可提供自定义实现。\n */\n applyFileData?: (file: DrawioFile, xml: string) => void;\n}\n\n/**\n * 默认只调用 `file.ui.setFileData(xml)` 重建 UI(pages / mxGraphModel),\n * 有意跳过 `file.setData(xml)`:在 Yjs 驱动的协作场景下,`file.data`\n * 不是真实状态来源;调用 `setData` 会把文件标记为「已修改」,\n * draw.io 在没有配置存储后端时会弹出 \"Save diagrams to:\" 存储选择对话框。\n *\n * 若业务方确实需要同步 `file.data`(例如需要 `file.save()` 或依赖\n * `file.data` 的快照逻辑),可通过 `applyFileData` 选项覆写:\n *\n * ```ts\n * new Binding(file, {\n * doc,\n * applyFileData: (f, xml) => {\n * f.ui.setFileData(xml);\n * f.setData(xml);\n * },\n * });\n * ```\n */\nconst defaultApplyFileData = (file: DrawioFile, xml: string) => {\n file.ui.setFileData(xml);\n};\n\n/**\n * 把 file XML 中的 diagram 合并进 Y.Doc。仅在 merge 策略 + doc 已有数据时调用。\n * @returns 是否成功合并;解析失败时返回 false 由调用方回退到 replace。\n */\nfunction mergeFileIntoDoc(\n doc: Y.Doc,\n fileXml: string,\n strategy: \"merge-remote\" | \"merge-client\",\n): boolean {\n let parsed: unknown;\n try {\n parsed = parseXml(fileXml);\n } catch (err) {\n console.warn(\n \"[y-mxgraph] 合并失败,file XML 解析异常,回退到 replace:\",\n err,\n );\n return false;\n }\n\n const mxfileObj = (parsed as Record<string, unknown>)?.mxfile as\n | { diagram?: Array<Record<string, unknown>> }\n | undefined;\n if (!mxfileObj || !Array.isArray(mxfileObj.diagram)) {\n console.warn(\n \"[y-mxgraph] 合并失败,file XML 不是合法 mxfile,回退到 replace\",\n );\n return false;\n }\n\n const mxfileMap = doc.getMap(mxfileKey);\n const diagramMap = mxfileMap.get(diagramKey) as Y.Map<YDiagram> | undefined;\n const diagramOrder = mxfileMap.get(diagramOrderKey) as\n | Y.Array<string>\n | undefined;\n if (!diagramMap || !diagramOrder) {\n console.warn(\"[y-mxgraph] 合并失败,doc 结构不完整,回退到 replace\");\n return false;\n }\n\n doc.transact(() => {\n for (const diagram of mxfileObj.diagram!) {\n const id =\n ((diagram as { _attributes?: { id?: string } })._attributes\n ?.id as string) || \"\";\n if (!id) continue;\n\n const docHas = diagramMap.has(id);\n if (docHas && strategy === \"merge-remote\") {\n // doc 优先,跳过\n continue;\n }\n\n // 覆盖或新增\n const yDiagram = parseDiagram(\n diagram as unknown as import(\"../models/diagram\").Diagram,\n );\n diagramMap.set(id, yDiagram);\n if (!docHas) {\n diagramOrder.push([id]);\n }\n }\n });\n return true;\n}\n\nfunction reconcileInitialContent(\n doc: Y.Doc,\n file: DrawioFile,\n strategy: InitialContentStrategy,\n applyFileData: (file: DrawioFile, xml: string) => void,\n): boolean {\n const mxfileMap = doc.getMap(mxfileKey);\n const docHasData = mxfileMap.size > 0;\n // 与旧 demo 行为保持一致:file 是否「有任何数据」用 truthy 判断;\n // 只有完全空时才注入模板,避免把 draw.io 默认文件覆盖成模板触发\n // 「Save diagrams to:」存储选择对话框。\n const fileHasAnyData = !!file.data;\n // merge 策略需要进一步判断是否存在真实 diagram 内容\n const fileHasDiagrams = fileHasAnyData && file.data.includes(\"<diagram\");\n\n if (strategy === \"replace\") {\n if (docHasData) {\n const xml = doc2xml(doc);\n if (xml && xml.includes(\"<diagram\")) {\n applyFileData(file, xml);\n } else if (!fileHasAnyData) {\n applyFileData(file, Binding.generateFileTemplate(\"diagram-0\"));\n }\n } else if (!fileHasAnyData) {\n applyFileData(file, Binding.generateFileTemplate(\"diagram-0\"));\n }\n // 其余情况保留 file,避免触发 draw.io 默认文件的存储对话框\n return mxfileMap.size > 0;\n }\n\n // merge-remote / merge-client\n if (!docHasData && !fileHasDiagrams) {\n if (!fileHasAnyData) {\n applyFileData(file, Binding.generateFileTemplate(\"diagram-0\"));\n }\n return false;\n }\n\n if (!docHasData && fileHasDiagrams) {\n // 仅 file 有 → 把 file 写入 doc,file 保持不变\n try {\n doc.transact(() => {\n xml2doc(file.data, doc);\n });\n return true;\n } catch (err) {\n console.warn(\n \"[y-mxgraph] merge 模式下 xml2doc 失败,回退 replace:\",\n err,\n );\n applyFileData(file, Binding.generateFileTemplate(\"diagram-0\"));\n return false;\n }\n }\n\n if (docHasData && !fileHasDiagrams) {\n // 仅 doc 有可用 diagram → 用 doc 覆盖 file\n const xml = doc2xml(doc);\n if (xml && xml.includes(\"<diagram\")) {\n applyFileData(file, xml);\n } else if (!fileHasAnyData) {\n applyFileData(file, Binding.generateFileTemplate(\"diagram-0\"));\n }\n return mxfileMap.size > 0;\n }\n\n // 双方都有可用 diagram → 按策略合并\n const ok = mergeFileIntoDoc(doc, file.data, strategy);\n if (!ok) {\n // 解析失败回退到 replace(用 doc 覆盖 file)\n const xml = doc2xml(doc);\n if (xml && xml.includes(\"<diagram\")) applyFileData(file, xml);\n return mxfileMap.size > 0;\n }\n const xml = doc2xml(doc);\n if (xml && xml.includes(\"<diagram\")) applyFileData(file, xml);\n return true;\n}\n\n/**\n * Y-MXGraph 绑定类,管理 draw.io 文件与 Y.Doc 的双向同步\n *\n * 初始化流程对齐 y-prosemirror 等数据源:\n * - 绑定时不向 Y.Doc 写入初始数据\n * - 在第一次本地编辑时才初始化 Y.Doc\n * - 新客户端加入时,同步已有的远端数据到本地\n */\nexport class Binding {\n /** Y.Doc 实例,用于协同数据存储 */\n readonly doc: Y.Doc;\n /** mxGraph 的数据模型,用于监听本地变更 */\n private mxGraphModel: MxGraphModel;\n /** 本地变更抑制标志,防止循环同步 */\n private suppressLocalApply = false;\n /** 初始化标志,标记 Y.Doc 是否已初始化 */\n private docInitialized = false;\n /** mxGraph change 事件监听器 */\n private mxListener: () => void;\n /** Yjs 文档深度变更监听器 */\n private docObserver: (\n events: Y.YEvent<\n Y.XmlElement | Y.Array<string> | Y.Map<Y.XmlElement> | YMxFile\n >[],\n transaction: Y.Transaction,\n ) => void;\n /** 协作功能清理函数(awareness 光标/选区) */\n private cleanupCollaborator?: () => void;\n /** UndoManager 绑定清理函数 */\n private cleanupUndoManager?: () => void;\n\n constructor(file: DrawioFile, options: BindDrawioFileOptions) {\n const {\n doc,\n awareness,\n undoManager,\n mouseMoveThrottle,\n cursor,\n initialContent = \"replace\",\n applyFileData = defaultApplyFileData,\n } = options;\n\n this.doc = doc;\n\n const ui = file.getUi();\n const graph = ui.editor.graph;\n this.mxGraphModel = graph.model;\n\n // 统一初始化:根据 initialContent 策略对齐 file 与 doc。\n // 内部会调用 applyFileData 钩子(默认 ui.setFileData + file.setData),\n // 业务方不再需要在外部手动同步。\n this.suppressLocalApply = true;\n try {\n this.docInitialized = reconcileInitialContent(\n doc,\n file,\n initialContent,\n applyFileData,\n );\n // doc 在 reconcile 后才确定有内容,需建立 snapshot 基线\n if (this.docInitialized) {\n initDocSnapshot(doc, false);\n }\n } finally {\n this.suppressLocalApply = false;\n }\n\n // 对齐 shadowPages(reconcile 可能已经替换了 ui.pages)\n file.setShadowPages(file.ui.clonePages(file.ui.pages));\n\n // 本地变更监听\n this.mxListener = () => {\n if (this.suppressLocalApply) return;\n\n const patch = file.ui.diffPages(\n file.shadowPages,\n file.ui.pages,\n ) as import(\"./patch\").FilePatch;\n const patchKeys = Object.keys(patch);\n\n // 没有实际本地变更时直接跳过\n if (patchKeys.length === 0) return;\n\n // 第一次有实际本地编辑时才初始化 Y.Doc\n if (!this.docInitialized) {\n doc.transact(() => {\n xml2doc(file.data, doc);\n initDocSnapshot(doc, false);\n });\n this.docInitialized = true;\n }\n\n file.setShadowPages(file.ui.clonePages(file.ui.pages));\n applyFilePatch(doc, patch, { origin: LOCAL_ORIGIN });\n };\n this.mxGraphModel.addListener(\"change\", this.mxListener);\n\n // 远端变更监听\n this.docObserver = (\n events: Y.YEvent<\n Y.XmlElement | Y.Array<string> | Y.Map<Y.XmlElement> | YMxFile\n >[],\n transaction: Y.Transaction,\n ) => {\n // 标记已初始化(即使是远端数据到达)\n if (!this.docInitialized) {\n this.docInitialized = true;\n }\n\n if (transaction.local && transaction.origin === LOCAL_ORIGIN) {\n generatePatch(events);\n return;\n }\n\n const patch = generatePatch(events);\n if (Object.keys(patch).length === 0) return;\n this.suppressLocalApply = true;\n try {\n file.patch([patch]);\n file.setShadowPages(file.ui.clonePages(file.ui.pages));\n } finally {\n this.suppressLocalApply = false;\n }\n };\n doc.getMap(mxfileKey).observeDeep(this.docObserver);\n\n // 协作功能\n if (awareness) {\n this.cleanupCollaborator = bindCollaborator(file, {\n awareness,\n graph,\n cursor: cursor ?? true,\n mouseMoveThrottle,\n });\n }\n\n // UndoManager\n if (undoManager) {\n this.cleanupUndoManager = bindUndoManager(doc, file, undoManager);\n }\n }\n\n /**\n * 销毁绑定,解除所有监听器\n * @param deep - 是否深度清理(包括 awareness/undoManager),默认 false\n */\n destroy(deep = false): void {\n this.mxGraphModel.removeListener(\"change\", this.mxListener);\n this.doc.getMap(mxfileKey).unobserveDeep(this.docObserver);\n if (deep) {\n this.cleanupCollaborator?.();\n this.cleanupUndoManager?.();\n }\n }\n\n /**\n * 生成标准化的 mxfile XML 模板,用于确保多端协同的数据起点一致。\n *\n * draw.io 每次新建 diagram 时默认生成随机 id(如 `DEMOabHTdChjKBf1yHdD`)。\n * 如果各客户端初始化时的 diagram id 不同,Y.Doc 中的数据与本地 file.data 无法对齐,\n * 会导致:\n * - 后进房间的客户端出现「孤立 page」(来自本地 XML,未写入 Y.Doc)\n * - patch 的 diff 无法正确匹配 diagram/cell id,协同失效\n *\n * 因此业务方应在初始化 draw.io 文件时,先用此方法生成统一起点的 XML,\n * 再注入到 draw.io 的 currentFile 中(详见文档「接入注意事项」)。\n *\n * @param diagramId - diagram 的固定 id,默认 `diagram-0`\n * @returns 最小化的 mxfile XML 字符串\n */\n static generateFileTemplate(diagramId = \"diagram-0\"): string {\n return `<mxfile pages=\"1\">\n <diagram id=\"${diagramId}\">\n <mxGraphModel>\n <root>\n <mxCell id=\"0\" />\n <mxCell id=\"1\" parent=\"0\" />\n </root>\n </mxGraphModel>\n </diagram>\n</mxfile>`;\n }\n\n /**\n * 静态工厂方法,创建 Binding 实例\n * 与 `new Binding()` 等价\n */\n static create(file: DrawioFile, options: BindDrawioFileOptions): Binding {\n return new Binding(file, options);\n }\n}\n"],"names":["key","parse","xml2js","serializer","js2xml","Y","serialize","mxCellKey","parseMxCell","serializeMxCell","parseMxGraphModel","mxGraphModelKey","serializeMxGraphModel","diagramKey","parseDiagram","_a","serializeDiagram","mxfileKey","id","orderArr","xmlSerializer","parseMxFile","serializerMxFile","serializerMxGraphModel","CacheKey","colord","throttle","parseXml","xml"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"y-mxgraph.iife.js","sources":["../src/helper/xml.ts","../src/models/mxCell.ts","../src/models/mxGraphModel.ts","../src/models/diagram.ts","../src/models/mxfile.ts","../src/binding/patch.ts","../src/transformer/index.ts","../src/helper/origin.ts","../src/binding/undoManager.ts","../src/helper/awarenessStateValue.ts","../src/helper/random.ts","../src/helper/cursor.ts","../src/binding/collaborator/cursor.ts","../src/helper/getId.ts","../src/binding/collaborator/selection.ts","../src/binding/collaborator/index.ts","../src/binding/index.ts"],"sourcesContent":["import { xml2js, js2xml, type ElementCompact } from \"xml-js\";\n\nfunction deepProcess(node: unknown): void {\n if (node == null) return;\n\n if (Array.isArray(node)) {\n for (const item of node) {\n deepProcess(item);\n }\n return;\n }\n\n if (typeof node !== \"object\") return;\n\n const obj = node as Record<string, unknown>;\n const keys = Object.keys(obj);\n for (const key of keys) {\n if (key === \"_attributes\") continue;\n\n let value = obj[key];\n const keyLower = key.toLowerCase();\n\n if (\n (keyLower === \"diagram\" || keyLower === \"mxcell\") &&\n value !== undefined &&\n !Array.isArray(value)\n ) {\n obj[key] = [value];\n value = obj[key];\n }\n\n if (Array.isArray(value)) {\n for (const v of value) deepProcess(v);\n } else if (value && typeof value === \"object\") {\n deepProcess(value);\n }\n }\n}\n\nexport function parse(xml: string) {\n const result = xml2js(xml, { compact: true }) as Record<string, unknown>;\n deepProcess(result);\n return result;\n}\n\nexport function serializer(obj: ElementCompact, spaces = 2) {\n return js2xml(obj, {\n compact: true,\n spaces,\n });\n}\n","import * as Y from \"yjs\";\nimport { xml2js, js2xml } from \"xml-js\";\nimport type { ElementCompact } from \"xml-js\";\n\nexport const key = \"mxCell\";\n\nconst mxGeometryKey = \"mxGeometry\";\nconst mxGeometryAttributeKey = \"geometry\";\n\nexport interface MxCellModel extends ElementCompact {\n [mxGeometryKey]?: ElementCompact;\n}\n\nexport function parse(object: MxCellModel): Y.XmlElement {\n const xmlElement = new Y.XmlElement(\"mxCell\");\n\n for (const attribute of Object.keys(object._attributes || {})) {\n xmlElement.setAttribute(\n attribute,\n `${object._attributes?.[attribute] || \"\"}`\n );\n }\n\n if (object[mxGeometryKey]) {\n const geometry = object[mxGeometryKey];\n const geometryString = js2xml(geometry, {\n compact: true,\n });\n xmlElement.setAttribute(mxGeometryAttributeKey, geometryString);\n delete object[mxGeometryKey];\n }\n\n return xmlElement;\n}\n\nexport function serialize(xmlElement: Y.XmlElement) {\n const rawAttributes = {\n ...xmlElement.getAttributes(),\n };\n\n // 提取 mxGeometry(不需要转义,它本身就是 XML 字符串)\n let mxGeometry: ElementCompact | null = null;\n let mxGeometryString: string | undefined;\n\n if (mxGeometryAttributeKey in rawAttributes) {\n mxGeometryString = rawAttributes[mxGeometryAttributeKey];\n delete rawAttributes[mxGeometryAttributeKey];\n }\n\n // 转义其他属性值中的特殊字符\n const attributes: Record<string, string> = {};\n for (const [key, value] of Object.entries(rawAttributes)) {\n if (typeof value === 'string') {\n attributes[key] = value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n } else if (value != null) {\n attributes[key] = String(value);\n }\n }\n\n // 解析 mxGeometry\n if (mxGeometryString) {\n try {\n const parsed = xml2js(mxGeometryString, { compact: true }) as Record<string, ElementCompact>;\n mxGeometry = parsed[mxGeometryKey] ?? null;\n if (mxGeometry && mxGeometry._attributes) {\n mxGeometry._attributes[\"as\"] = \"geometry\";\n }\n } catch (e) {\n console.warn(\"[y-mxgraph] Failed to parse mxGeometry:\", e);\n }\n }\n\n const obj: Record<string, unknown> = {\n _attributes: attributes,\n };\n\n if (mxGeometry) {\n obj[mxGeometryKey] = mxGeometry;\n }\n\n return obj;\n}\n","import * as Y from \"yjs\";\n\nimport {\n key as mxCellKey,\n parse as parseMxCell,\n serialize as serializeMxCell,\n type MxCellModel,\n} from \"./mxCell\";\nimport type { ElementCompact } from \"xml-js\";\n\nexport const key = \"mxGraphModel\";\nexport const mxCellOrderKey = mxCellKey + \"Order\";\n\nexport interface MxGraphModel extends ElementCompact {\n root: {\n mxCell: MxCellModel[];\n };\n}\n\nexport type YMxGraphModel = Y.Map<unknown>;\n\nexport function parse(object: MxGraphModel, doc?: Y.Doc) {\n const mxCells = (object.root[mxCellKey] || []).map((cell: MxCellModel) => {\n return {\n value: parseMxCell(cell),\n id: (cell._attributes?.id || \"\") as string,\n };\n });\n\n const mxGraphElement = doc?.getMap(key) || new Y.Map();\n\n const cells = new Y.Map<Y.XmlElement>();\n const cellsOrder = new Y.Array<string>();\n\n mxCells.forEach((cell) => {\n cells.set(cell.id, cell.value);\n });\n\n cellsOrder.push(mxCells.map((cell) => cell.id));\n\n mxGraphElement.set(mxCellKey, cells);\n mxGraphElement.set(mxCellOrderKey, cellsOrder);\n\n return mxGraphElement as YMxGraphModel;\n}\n\nexport function serialize(map: YMxGraphModel) {\n const cells = map.get(mxCellKey) as unknown as Y.Map<Y.XmlElement>;\n const cellsOrder = map.get(mxCellOrderKey) as unknown as Y.Array<string>;\n return {\n _attributes: {},\n root: {\n [mxCellKey]: cellsOrder\n .toArray()\n .map((id) => serializeMxCell(cells.get(id) as Y.XmlElement)),\n },\n };\n}\n","import * as Y from \"yjs\";\nimport {\n parse as parseMxGraphModel,\n serialize as serializeMxGraphModel,\n key as mxGraphModelKey,\n type MxGraphModel,\n type YMxGraphModel,\n} from \"./mxGraphModel\";\nimport type { ElementCompact } from \"xml-js\";\n\nexport const key = \"diagram\";\n\nexport interface Diagram extends ElementCompact {\n mxGraphModel: MxGraphModel;\n}\n\nexport type YDiagram = Y.Map<unknown>;\n\nexport function parse(object: Diagram): YDiagram {\n const yDiagramElement = new Y.Map();\n yDiagramElement.set(\"name\", `${object._attributes?.name || \"\"}`);\n yDiagramElement.set(\"id\", `${object._attributes?.id || \"\"}`);\n\n const mxGraphModel = parseMxGraphModel(object[mxGraphModelKey]);\n\n yDiagramElement.set(mxGraphModelKey, mxGraphModel);\n return yDiagramElement as YDiagram;\n}\n\nexport function serialize(yDiagram: YDiagram) {\n const mxGraphModel = yDiagram.get(mxGraphModelKey) as unknown as\n | YMxGraphModel\n | undefined;\n\n return {\n _attributes: {\n name: yDiagram.get(\"name\") as unknown as string,\n id: yDiagram.get(\"id\") as unknown as string,\n },\n [mxGraphModelKey]: mxGraphModel\n ? serializeMxGraphModel(mxGraphModel)\n : undefined,\n };\n}\n","import * as Y from \"yjs\";\nimport {\n parse as parseDiagram,\n key as diagramKey,\n serialize as serializeDiagram,\n} from \"./diagram\";\nimport type { Diagram, YDiagram } from \"./diagram\";\nimport type { ElementCompact } from \"xml-js\";\n\nexport const key = \"mxfile\";\nexport const diagramOrderKey = diagramKey + \"Order\";\n\nexport type YMxFile = Y.Map<unknown>;\n\nexport interface MxFile extends ElementCompact {\n diagram: Diagram[];\n}\n\nexport function parse(object: MxFile, doc: Y.Doc) {\n const mxfile = doc.getMap(key);\n mxfile.set(\"pages\", (object._attributes?.pages || \"1\") + \"\");\n\n const diagramList = object.diagram.map((diagram) => ({\n value: parseDiagram(diagram),\n id: (diagram._attributes?.id || \"\") as string,\n }));\n const diagramMap = new Y.Map<YDiagram>();\n const diagramOrder = new Y.Array<string>();\n diagramList.forEach((diagram) => {\n diagramMap.set(diagram.id, diagram.value);\n });\n diagramOrder.push(diagramList.map((diagram) => diagram.id));\n\n mxfile.set(diagramKey, diagramMap);\n mxfile.set(diagramOrderKey, diagramOrder);\n return mxfile;\n}\n\nexport function serializer(yMxFile: YMxFile): ElementCompact {\n const diagrams = yMxFile.get(diagramKey) as unknown as Y.Map<YDiagram>;\n const diagramOrder = yMxFile.get(\n diagramOrderKey,\n ) as unknown as Y.Array<string>;\n\n const orderIds = diagramOrder ? diagramOrder.toArray() : [];\n // 如果 diagramOrder 为空但 diagram map 不为空,使用 diagram map 中的所有 ID\n const ids = orderIds.length > 0 ? orderIds : (diagrams ? Array.from(diagrams.keys()) : []);\n\n const obj: Record<string, unknown> = {\n _attributes: {\n pages: (yMxFile.get(\"pages\") as string) || \"1\",\n },\n [diagramKey]: ids\n .map((id) => diagrams.get(id) as unknown as YDiagram)\n .filter((d): d is YDiagram => !!d)\n .map((diagramElement) => serializeDiagram(diagramElement)),\n };\n\n return obj as ElementCompact;\n}\n","import { parse, serializer as xmlSerializer } from \"../helper/xml\";\nimport {\n parse as parseDiagram,\n key as diagramKey,\n serialize as serializeDiagram,\n type YDiagram,\n} from \"../models/diagram\";\nimport {\n key as mxfileKey,\n type YMxFile,\n diagramOrderKey,\n} from \"../models/mxfile\";\nimport {\n mxCellOrderKey,\n key as mxGraphModelKey,\n type YMxGraphModel,\n} from \"../models/mxGraphModel\";\nimport { key as mxCellKey } from \"../models/mxCell\";\nimport * as Y from \"yjs\";\n\nconst DIFF_INSERT = \"i\";\nconst DIFF_REMOVE = \"r\";\nconst DIFF_UPDATE = \"u\";\n\ntype DocSnapshot = {\n diagramOrder: string[] | null;\n cellsOrder: Map<string, string[]>;\n cellAttrs: Map<string, Map<string, Record<string, string>>>;\n};\nconst docSnapshots = new WeakMap<Y.Doc, DocSnapshot>();\n\nfunction insertAfterUnique(\n orderArr: Y.Array<string>,\n id: string,\n previous: string | null | undefined,\n fallbackToEnd = false,\n) {\n const currentIds = orderArr.toArray();\n let anchorPos = previous ? currentIds.indexOf(previous) : -1;\n if (anchorPos === -1 && fallbackToEnd) anchorPos = currentIds.length - 1;\n let targetIndex = anchorPos + 1;\n\n const existingIndex = currentIds.indexOf(id);\n if (existingIndex === -1) {\n orderArr.insert(targetIndex, [id]);\n return;\n }\n\n if (existingIndex === targetIndex) return;\n\n if (existingIndex < targetIndex) targetIndex -= 1;\n orderArr.delete(existingIndex, 1);\n orderArr.insert(targetIndex, [id]);\n}\n\nfunction ensureUniqueOrder(orderArr: Y.Array<string>) {\n const arr = orderArr.toArray();\n const seen = new Set<string>();\n const dupIdx: number[] = [];\n for (let i = 0; i < arr.length; i++) {\n const id = arr[i];\n if (!id) continue;\n if (seen.has(id)) dupIdx.push(i);\n else seen.add(id);\n }\n if (dupIdx.length) {\n dupIdx.sort((a, b) => b - a).forEach((idx) => orderArr.delete(idx, 1));\n }\n}\n\nexport interface DiagramInsert {\n data: string;\n id: string;\n previous: string;\n}\n\nexport interface FilePatch {\n [DIFF_REMOVE]?: string[];\n [DIFF_INSERT]?: DiagramInsert[];\n [DIFF_UPDATE]?: {\n [key: string]: {\n name?: string;\n previous?: string;\n cells?: {\n [DIFF_REMOVE]?: string[];\n [DIFF_INSERT]?: Record<string, string>[];\n [DIFF_UPDATE]?: {\n [key: string]: Record<string, string>;\n };\n };\n };\n };\n}\n\nexport function applyFilePatch(\n doc: Y.Doc,\n patch: FilePatch,\n options?: { origin?: unknown },\n) {\n doc.transact(() => {\n const mxfile = doc.getMap(mxfileKey) as YMxFile;\n if (patch[DIFF_REMOVE]) {\n const diagramsMap = mxfile.get(diagramKey) as unknown as Y.Map<YDiagram>;\n const orderArr = mxfile.get(\n diagramOrderKey,\n ) as unknown as Y.Array<string>;\n ensureUniqueOrder(orderArr);\n const orderList = orderArr.toArray();\n\n const removeIds = patch[DIFF_REMOVE];\n if (removeIds && removeIds.length) {\n const indexList = removeIds\n .map((id) => orderList.indexOf(id))\n .filter((i) => i !== -1)\n .sort((a, b) => b - a);\n\n indexList.forEach((idx) => orderArr.delete(idx, 1));\n removeIds.forEach((id) => diagramsMap.delete(id));\n }\n }\n\n if (patch[DIFF_INSERT]) {\n const diagramsMap = mxfile.get(diagramKey) as unknown as Y.Map<YDiagram>;\n const orderArr = mxfile.get(\n diagramOrderKey,\n ) as unknown as Y.Array<string>;\n ensureUniqueOrder(orderArr);\n \n // 确保 diagramOrder 包含所有 diagram map 中的 IDs\n const currentOrder = orderArr.toArray();\n if (currentOrder.length === 0 && diagramsMap && diagramsMap.size > 0) {\n const allIds = Array.from(diagramsMap.keys());\n orderArr.push(allIds);\n }\n ensureUniqueOrder(orderArr);\n \n const existingIds = orderArr.toArray();\n const existingIndex = new Map<string, number>();\n existingIds.forEach((id, idx) => existingIndex.set(id, idx));\n\n const inserts = patch[DIFF_INSERT].map((item, order) => {\n const object = parse(item.data) as Record<string, unknown>;\n const diagramObj = Array.isArray(object?.diagram)\n ? (object.diagram as unknown[])[0]\n : object?.diagram;\n const diagramElement = parseDiagram(\n diagramObj as import(\"../models/diagram\").Diagram,\n );\n return {\n id: item.id,\n previous: item.previous || \"\",\n diagramElement,\n order,\n };\n });\n\n const byId = new Map(inserts.map((i) => [i.id, i] as const));\n const computeAnchor = (node: {\n id: string;\n previous: string;\n }): {\n anchorId: string;\n depth: number;\n } => {\n let depth = 1;\n let anchorId = \"\";\n let prevId = node.previous;\n const seen = new Set<string>([node.id]);\n while (prevId) {\n if (seen.has(prevId)) {\n depth = 1;\n anchorId = \"\";\n break;\n }\n seen.add(prevId);\n\n const prevNode = byId.get(prevId);\n if (prevNode) {\n depth += 1;\n prevId = prevNode.previous;\n continue;\n }\n\n if (existingIndex.has(prevId)) {\n anchorId = prevId;\n } else {\n anchorId = \"\";\n }\n break;\n }\n return { anchorId, depth };\n };\n\n const enriched = inserts.map((i) => ({ ...i, ...computeAnchor(i) }));\n\n enriched.sort((a, b) => {\n const aIdx = a.anchorId ? existingIndex.get(a.anchorId)! : -1;\n const bIdx = b.anchorId ? existingIndex.get(b.anchorId)! : -1;\n if (aIdx !== bIdx) return aIdx - bIdx;\n if (a.depth !== b.depth) return b.depth - a.depth;\n return b.order - a.order;\n });\n\n for (const item of enriched) {\n diagramsMap.set(item.id, item.diagramElement);\n insertAfterUnique(orderArr, item.id, item.anchorId || null);\n }\n }\n\n if (patch[DIFF_UPDATE]) {\n Object.keys(patch[DIFF_UPDATE]).forEach((id) => {\n const diagramsMap = mxfile.get(\n diagramKey,\n ) as unknown as Y.Map<YDiagram>;\n const diagram = diagramsMap.get(id) as YDiagram | undefined;\n if (diagram) {\n const update = patch[DIFF_UPDATE]![id];\n if (\"name\" in update) {\n (diagram as unknown as Y.Map<unknown>).set(\n \"name\",\n update.name || \"\",\n );\n }\n\n if (update.cells) {\n const yMxGraphModel = diagram.get(mxGraphModelKey) as\n | YMxGraphModel\n | undefined;\n if (!yMxGraphModel) return;\n const cellsMap = yMxGraphModel.get(mxCellKey) as\n | Y.Map<Y.XmlElement>\n | undefined;\n const orderArr = yMxGraphModel.get(mxCellOrderKey) as\n | Y.Array<string>\n | undefined;\n if (!cellsMap || !orderArr) return;\n ensureUniqueOrder(orderArr as Y.Array<string>);\n\n if (update.cells[DIFF_REMOVE] && update.cells[DIFF_REMOVE].length) {\n const orderIds = orderArr.toArray();\n const removeIndexList = update.cells[DIFF_REMOVE].map((cid) =>\n orderIds.indexOf(cid),\n )\n .filter((i) => i !== -1)\n .sort((a, b) => b - a);\n removeIndexList.forEach((idx) => orderArr.delete(idx, 1));\n update.cells[DIFF_REMOVE].forEach((cid) => cellsMap.delete(cid));\n }\n\n if (update.cells[DIFF_INSERT] && update.cells[DIFF_INSERT].length) {\n for (const item of update.cells[DIFF_INSERT]) {\n const id = item[\"id\"] as string | undefined;\n if (!id) continue;\n const xmlElement = new Y.XmlElement(\"mxCell\");\n Object.keys(item).forEach((key) => {\n if (key === \"previous\") return;\n xmlElement.setAttribute(key, item[key]);\n });\n cellsMap.set(id, xmlElement);\n const previous = item[\"previous\"] as string | undefined;\n const parent = item[\"parent\"] as string | undefined;\n let anchorId: string | null | undefined = null;\n let fallbackToEnd = true;\n if (typeof previous !== \"undefined\") {\n if (previous === \"\") {\n if (parent) {\n anchorId = parent;\n fallbackToEnd = true;\n } else {\n anchorId = null;\n fallbackToEnd = false;\n }\n } else {\n anchorId = previous;\n fallbackToEnd = true;\n }\n } else if (parent) {\n anchorId = parent;\n fallbackToEnd = true;\n }\n\n insertAfterUnique(\n orderArr as Y.Array<string>,\n id,\n anchorId,\n fallbackToEnd,\n );\n }\n }\n\n if (update.cells[DIFF_UPDATE]) {\n Object.keys(update.cells[DIFF_UPDATE]).forEach((cid) => {\n const updateObj = update.cells![DIFF_UPDATE]![cid];\n const cell = cellsMap.get(cid) as Y.XmlElement | undefined;\n if (cell) {\n Object.keys(updateObj).forEach((k) => {\n if (k === \"previous\") return;\n cell.setAttribute(k, updateObj[k]);\n });\n }\n });\n\n Object.keys(update.cells[DIFF_UPDATE]).forEach((cellId) => {\n const updateObj = update.cells![DIFF_UPDATE]![cellId];\n const hasPrev = \"previous\" in updateObj;\n const hasParent = \"parent\" in updateObj;\n if (!hasPrev && !hasParent) return;\n\n const prevVal = hasPrev\n ? (updateObj.previous as string)\n : undefined;\n const parentVal = hasParent\n ? (updateObj.parent as string)\n : undefined;\n\n let anchorId: string | null | undefined = null;\n let fallbackToEnd = true;\n\n if (hasPrev) {\n if (prevVal === \"\") {\n if (parentVal) {\n anchorId = parentVal;\n fallbackToEnd = true;\n } else {\n anchorId = null;\n fallbackToEnd = false;\n }\n } else {\n anchorId = prevVal;\n fallbackToEnd = true;\n }\n } else if (parentVal) {\n anchorId = parentVal;\n fallbackToEnd = true;\n }\n\n const currentIds = orderArr.toArray();\n const currentIndex = currentIds.indexOf(cellId);\n\n if (currentIndex === -1) {\n let newCell = cellsMap.get(cellId) as\n | Y.XmlElement\n | undefined;\n if (!newCell) {\n newCell = new Y.XmlElement(\"mxCell\");\n newCell.setAttribute(\"id\", cellId);\n Object.keys(updateObj).forEach((k) => {\n if (k === \"previous\") return;\n newCell!.setAttribute(k, updateObj[k] as string);\n });\n cellsMap.set(cellId, newCell);\n }\n insertAfterUnique(\n orderArr as Y.Array<string>,\n cellId,\n anchorId,\n fallbackToEnd,\n );\n return;\n }\n\n insertAfterUnique(\n orderArr as Y.Array<string>,\n cellId,\n anchorId,\n fallbackToEnd,\n );\n });\n }\n }\n\n if (\"previous\" in update) {\n const previous = update.previous || null;\n const orderArr = mxfile.get(\n diagramOrderKey,\n ) as unknown as Y.Array<string>;\n ensureUniqueOrder(orderArr);\n insertAfterUnique(orderArr, id, previous, false);\n }\n }\n });\n }\n }, options?.origin);\n}\n\nexport function initDocSnapshot(doc: Y.Doc, resetSnapshot = false) {\n try {\n const mxfile = doc.getMap(mxfileKey) as YMxFile;\n const diagramsMap = mxfile.get(diagramKey) as unknown as Y.Map<YDiagram>;\n const orderArr = mxfile.get(diagramOrderKey) as unknown as Y.Array<string>;\n \n // 如果 diagramOrder 为空但 diagram map 不为空,使用 diagram map 中的所有 ID\n const orderIds = orderArr ? orderArr.toArray() : [];\n const allDiagramIds = orderIds.length > 0 \n ? orderIds \n : (diagramsMap ? Array.from(diagramsMap.keys()) : []);\n \n // resetSnapshot=true 时把 diagramOrder 设为空数组,\n // 使第一次 generatePatch 把所有现有 diagram/cells 都识别为 insert\n const diagramOrder = resetSnapshot ? [] : allDiagramIds.slice();\n\n const snap: DocSnapshot = {\n diagramOrder,\n cellsOrder: new Map<string, string[]>(),\n cellAttrs: new Map<string, Map<string, Record<string, string>>>(),\n };\n\n const diagrams: YDiagram[] = diagramOrder\n .map((id) => diagramsMap.get(id) as YDiagram | undefined)\n .filter((d): d is YDiagram => !!d);\n for (const d of diagrams) {\n const did = (d.get(\"id\") as unknown as string) || \"\";\n if (!did) continue;\n const gm = d.get(mxGraphModelKey) as YMxGraphModel | undefined;\n if (gm) {\n const order = gm.get(mxCellOrderKey) as Y.Array<string> | undefined;\n const ids = order ? order.toArray().slice() : [];\n snap.cellsOrder.set(did, ids);\n const cellsMap = gm.get(mxCellKey) as Y.Map<Y.XmlElement> | undefined;\n const attrMap = new Map<string, Record<string, string>>();\n if (cellsMap) {\n for (const cid of ids) {\n const el = cellsMap.get(cid) as Y.XmlElement | undefined;\n if (el) {\n attrMap.set(\n cid,\n (el.getAttributes() as Record<string, string>) || {},\n );\n }\n }\n }\n snap.cellAttrs.set(did, attrMap);\n } else {\n snap.cellsOrder.set(did, []);\n snap.cellAttrs.set(did, new Map());\n }\n }\n\n docSnapshots.set(doc, snap);\n } catch (e) {\n console.warn(\"[y-mxgraph] initDocSnapshot failed:\", e);\n }\n}\n\nexport function generatePatch(\n events: Y.YEvent<\n Y.XmlElement | Y.Array<string> | Y.Map<Y.XmlElement> | YMxFile | YDiagram\n >[],\n explicitDoc?: Y.Doc,\n): FilePatch {\n const patch: FilePatch = {};\n\n const doc =\n explicitDoc ??\n (events[0] as unknown as { transaction?: { doc?: Y.Doc } } | undefined)\n ?.transaction?.doc;\n if (!doc) return patch;\n if (!explicitDoc && (!events || events.length === 0)) return patch;\n const mxfile = doc.getMap(mxfileKey) as YMxFile;\n const diagramsMap = mxfile.get(diagramKey) as unknown as Y.Map<YDiagram>;\n const orderArr = mxfile.get(diagramOrderKey) as unknown as Y.Array<string>;\n\n let snap = docSnapshots.get(doc);\n if (!snap) {\n snap = {\n diagramOrder: null,\n cellsOrder: new Map<string, string[]>(),\n cellAttrs: new Map<string, Map<string, Record<string, string>>>(),\n };\n docSnapshots.set(doc, snap);\n }\n const prevDiagramOrder = snap.diagramOrder;\n const prevCellsOrder = snap.cellsOrder;\n const prevCellsAttrs = snap.cellAttrs;\n\n const ensureUpdate = (diagramId: string) => {\n patch[DIFF_UPDATE] = patch[DIFF_UPDATE] || {};\n patch[DIFF_UPDATE]![diagramId] = patch[DIFF_UPDATE]![diagramId] || {};\n return patch[DIFF_UPDATE]![diagramId]!;\n };\n const ensureCellSection = (diagramId: string) => {\n const u = ensureUpdate(diagramId);\n u.cells = u.cells || {};\n return u.cells!;\n };\n\n // 如果 diagramOrder 为空但 diagram map 不为空,使用 diagram map 中的所有 ID\n const orderIds = orderArr.toArray();\n const currDiagramOrder = orderIds.length > 0 \n ? orderIds \n : (diagramsMap ? Array.from(diagramsMap.keys()) : []);\n const diagramsList = currDiagramOrder\n .map((id) => diagramsMap.get(id) as YDiagram | undefined)\n .filter((d): d is YDiagram => !!d);\n const currCellsOrder = new Map<string, string[]>();\n const cellAttrMap = new Map<string, Map<string, Record<string, string>>>();\n\n for (const d of diagramsList) {\n const did = (d.get(\"id\") as unknown as string) || \"\";\n const attrs = new Map<string, Record<string, string>>();\n const gm = d.get(mxGraphModelKey) as YMxGraphModel | undefined;\n if (gm) {\n const cellsMap = gm.get(mxCellKey) as Y.Map<Y.XmlElement> | undefined;\n const orderArr = gm.get(mxCellOrderKey) as Y.Array<string> | undefined;\n if (cellsMap && orderArr) {\n const ids = orderArr.toArray();\n currCellsOrder.set(did, ids);\n for (const cid of ids) {\n const c = cellsMap.get(cid) as Y.XmlElement | undefined;\n if (c)\n attrs.set(cid, (c.getAttributes() as Record<string, string>) || {});\n }\n } else {\n currCellsOrder.set(did, []);\n }\n } else {\n currCellsOrder.set(did, []);\n }\n cellAttrMap.set(did, attrs);\n }\n\n const insertedDiagramIdGlobal = new Set<string>();\n const insertedCellIdGlobal = new Set<string>();\n\n if (prevDiagramOrder) {\n const prevSet = new Set(prevDiagramOrder);\n const currSet = new Set(currDiagramOrder);\n\n const removed = prevDiagramOrder.filter(\n (id: string) => !currSet.has(id) && id,\n );\n if (removed.length) patch[DIFF_REMOVE] = removed;\n const removedDiagramSet = new Set(removed);\n\n const inserted = currDiagramOrder.filter(\n (id: string) => !prevSet.has(id) && id,\n );\n if (inserted.length) {\n patch[DIFF_INSERT] = patch[DIFF_INSERT] || [];\n for (const id of inserted) {\n const index = currDiagramOrder.indexOf(id);\n const previous = index <= 0 ? \"\" : currDiagramOrder[index - 1];\n const yDiagram = diagramsMap.get(id) as YDiagram | undefined;\n if (!yDiagram) continue;\n const data = xmlSerializer({ diagram: serializeDiagram(yDiagram) });\n patch[DIFF_INSERT]!.push({ id, previous, data });\n insertedDiagramIdGlobal.add(id);\n }\n }\n\n const prevNeighbor = (order: string[], id: string) => {\n const i = order.indexOf(id);\n return i <= 0 ? \"\" : order[i - 1];\n };\n const common = currDiagramOrder.filter((id) => prevSet.has(id) && id);\n for (const id of common) {\n const prevP = prevNeighbor(prevDiagramOrder, id);\n const currP = prevNeighbor(currDiagramOrder, id);\n if (prevP !== currP) {\n if (prevP && removedDiagramSet.has(prevP)) continue;\n const u = ensureUpdate(id);\n u.previous = currP;\n }\n }\n }\n\n const allDiagramIds = new Set<string>([\n ...(prevDiagramOrder || []),\n ...currDiagramOrder,\n ]);\n for (const did of allDiagramIds) {\n if (!did) continue;\n const prevCells = prevCellsOrder.get(did) || [];\n const currCells = currCellsOrder.get(did) || [];\n if (!prevCells.length && !currCells.length) continue;\n\n const prevSet = new Set(prevCells);\n const currSet = new Set(currCells);\n\n const removed = prevCells.filter((cid: string) => !currSet.has(cid) && cid);\n if (removed.length) {\n const cells = ensureCellSection(did);\n cells[DIFF_REMOVE] = (cells[DIFF_REMOVE] || []).concat(removed);\n }\n const removedCellSet = new Set(removed);\n\n const inserted = currCells.filter(\n (cid: string) => !prevSet.has(cid) && cid,\n );\n if (inserted.length) {\n const cells = ensureCellSection(did);\n cells[DIFF_INSERT] = cells[DIFF_INSERT] || [];\n const attrsMap = cellAttrMap.get(did) || new Map();\n for (const cid of inserted) {\n const attrs = attrsMap.get(cid) || {};\n const index = currCells.indexOf(cid);\n const previous = index <= 0 ? \"\" : currCells[index - 1];\n cells[DIFF_INSERT]!.push({\n ...(attrs as Record<string, string>),\n previous,\n });\n insertedCellIdGlobal.add(cid);\n }\n }\n\n const prevNeighbor = (order: string[], id: string) => {\n const i = order.indexOf(id);\n return i <= 0 ? \"\" : order[i - 1];\n };\n const commonCells = currCells.filter((cid) => prevSet.has(cid) && cid);\n for (const cid of commonCells) {\n const prevP = prevNeighbor(prevCells, cid);\n const currP = prevNeighbor(currCells, cid);\n if (prevP !== currP) {\n if (prevP && removedCellSet.has(prevP)) continue;\n const cells = ensureCellSection(did);\n cells[DIFF_UPDATE] = cells[DIFF_UPDATE] || {};\n const cellUpdate = (cells[DIFF_UPDATE]![cid] =\n cells[DIFF_UPDATE]![cid] || {});\n (cellUpdate as Record<string, unknown>).previous = currP;\n }\n }\n }\n\n {\n const diagramSet = new Set<Y.Map<unknown>>(\n diagramsList as unknown as Y.Map<unknown>[],\n );\n for (const ev of events) {\n const target = (ev as unknown as { target?: unknown }).target;\n if (!(target instanceof Y.Map)) continue;\n if (!diagramSet.has(target)) continue;\n const changed: Set<string> =\n (ev as unknown as { keysChanged?: Set<string> }).keysChanged ||\n new Set();\n if (!changed || !changed.has(\"name\")) continue;\n const did = (target.get(\"id\") as unknown as string) || \"\";\n if (!did || insertedDiagramIdGlobal.has(did)) continue;\n const u = ensureUpdate(did);\n u.name = (target.get(\"name\") as unknown as string) || \"\";\n }\n }\n\n if (!prevDiagramOrder) {\n for (const d of diagramsList) {\n const did = (d.get(\"id\") as unknown as string) || \"\";\n if (!did) continue;\n const u = ensureUpdate(did);\n u.name = (d.get(\"name\") as unknown as string) || \"\";\n }\n }\n\n for (const ev of events) {\n const target = (ev as unknown as { target?: unknown }).target;\n if (!(target instanceof Y.XmlElement)) continue;\n const el = target as Y.XmlElement;\n if (el.nodeName !== \"mxCell\") continue;\n\n const changed: Set<string> =\n (ev as unknown as { attributesChanged?: Set<string> })\n .attributesChanged ||\n (ev as unknown as { keysChanged?: Set<string> }).keysChanged ||\n new Set();\n if (!changed || (changed as Set<string>).size === 0) continue;\n\n const cellId = el.getAttribute(\"id\");\n if (!cellId || insertedCellIdGlobal.has(cellId)) continue;\n\n const idsEntries = Array.from(currCellsOrder.entries());\n let diagramId = \"\";\n for (const [did, ids] of idsEntries) {\n if (ids.includes(cellId)) {\n diagramId = did;\n break;\n }\n }\n if (!diagramId) continue;\n\n const cellsPatch = ensureCellSection(diagramId);\n cellsPatch[DIFF_UPDATE] = cellsPatch[DIFF_UPDATE] || {};\n const cellUpdate = (cellsPatch[DIFF_UPDATE]![cellId] =\n cellsPatch[DIFF_UPDATE]![cellId] || {});\n for (const key of Array.from(changed)) {\n cellUpdate[key] = el.getAttribute(key) || \"\";\n }\n }\n\n if (prevDiagramOrder) {\n for (const [did, currAttrsMap] of cellAttrMap.entries()) {\n const prevAttrsMap =\n prevCellsAttrs.get(did) || new Map<string, Record<string, string>>();\n const cellsPatch = ensureCellSection(did);\n cellsPatch[DIFF_UPDATE] = cellsPatch[DIFF_UPDATE] || {};\n const updateBucket = cellsPatch[DIFF_UPDATE]!;\n\n const currCells = currAttrsMap.keys();\n for (const cid of currCells) {\n if (insertedCellIdGlobal.has(cid)) continue;\n const prevAttrs = prevAttrsMap.get(cid) || {};\n const currAttrs = currAttrsMap.get(cid) || {};\n const keys = new Set<string>([\n ...Object.keys(prevAttrs),\n ...Object.keys(currAttrs),\n ]);\n const cellUpdate = (updateBucket[cid] = updateBucket[cid] || {});\n let changed = false;\n for (const k of keys) {\n const pv = prevAttrs[k] ?? \"\";\n const cv = currAttrs[k] ?? \"\";\n if (pv !== cv) {\n cellUpdate[k] = cv;\n changed = true;\n }\n }\n if (!changed) {\n if (Object.keys(cellUpdate).length === 0) {\n delete updateBucket[cid];\n }\n }\n }\n }\n }\n\n snap.diagramOrder = currDiagramOrder.slice();\n const newCellsOrder = new Map<string, string[]>();\n const newCellsAttrs = new Map<string, Map<string, Record<string, string>>>();\n for (const [did, arr] of currCellsOrder.entries()) {\n newCellsOrder.set(did, arr.slice());\n }\n for (const [did, attrsMap] of cellAttrMap.entries()) {\n const copy = new Map<string, Record<string, string>>();\n for (const [cid, attrs] of attrsMap.entries()) {\n copy.set(cid, { ...attrs });\n }\n newCellsAttrs.set(did, copy);\n }\n snap.cellsOrder = newCellsOrder;\n snap.cellAttrs = newCellsAttrs;\n docSnapshots.set(doc, snap);\n\n return patch;\n}\n","import * as Y from \"yjs\";\nimport { parse, serializer } from \"../helper/xml\";\nimport {\n parse as parseMxFile,\n key as mxfileKey,\n serializer as serializerMxFile,\n type YMxFile,\n} from \"../models/mxfile\";\nimport {\n parse as parseMxGraphModel,\n key as mxGraphModelKey,\n serialize as serializerMxGraphModel,\n type YMxGraphModel,\n} from \"../models/mxGraphModel\";\n\nexport function xml2doc(xml: string, doc: Y.Doc): Y.Doc {\n const object = parse(xml);\n\n const mxfile = (object as Record<string, unknown>).mxfile;\n const mxGraphModel = (object as Record<string, unknown>).mxGraphModel;\n if (mxfile) {\n doc.transact(() => {\n parseMxFile(mxfile as import(\"../models/mxfile\").MxFile, doc);\n });\n } else if (mxGraphModel) {\n doc.transact(() => {\n parseMxGraphModel(mxGraphModel as import(\"../models/mxGraphModel\").MxGraphModel, doc);\n });\n } else {\n throw new Error(\"不支持的文件格式\");\n }\n\n return doc;\n}\n\nexport function doc2xml(doc: Y.Doc, spaces = 0): string {\n if (doc.share.has(mxfileKey)) {\n return serializer(\n {\n [mxfileKey]: serializerMxFile(\n doc.share.get(mxfileKey) as unknown as YMxFile,\n ),\n },\n spaces,\n );\n } else if (doc.share.has(mxGraphModelKey)) {\n return serializer(\n {\n [mxGraphModelKey]: serializerMxGraphModel(\n doc.share.get(mxGraphModelKey) as unknown as YMxGraphModel,\n ),\n },\n spaces,\n );\n }\n\n return \"\";\n}\n","/**\n * 本地修改事务的 origin 标记,供 UndoManager.trackedOrigins 使用。\n * 对外导出,外部创建 Y.UndoManager 时可将其加入 trackedOrigins,\n * 以确保只追踪 binding 内部产生的本地变更。\n */\nexport const LOCAL_ORIGIN: object = {};\n","/**\n * 绑定 Y.UndoManager 到 draw.io 的 editor.undoManager,提供 mxUndoManager 兼容层。\n * 仅在外部传入 undoManager 时调用。\n */\nimport * as Y from \"yjs\";\nimport { LOCAL_ORIGIN } from \"../helper/origin\";\nimport type { DrawioFile } from \"../types/drawio\";\n\ntype ListenerFn = (sender: unknown, evt?: unknown) => void;\n\nfunction createMxEventObject(name: string, props?: Record<string, unknown>) {\n const _props = props || {};\n return {\n name,\n getName: () => name,\n getProperty: (k: string) => _props[k],\n };\n}\n\nexport function bindUndoManager(doc: Y.Doc, file: DrawioFile, yUndo: Y.UndoManager) {\n const editor = file.getUi().editor;\n const originUndoManager = editor.undoManager;\n\n let lastTxnLocalOrigin = false;\n const beforeTxnHandler = (t: Y.Transaction) => {\n lastTxnLocalOrigin = !!(t.local || t.origin === LOCAL_ORIGIN);\n };\n const afterTxnHandler = (t: Y.Transaction) => {\n lastTxnLocalOrigin = !!(t.local || t.origin === LOCAL_ORIGIN);\n };\n doc.on(\"beforeTransaction\", beforeTxnHandler);\n doc.on(\"afterTransaction\", afterTxnHandler);\n\n const pairs: Array<[string, ListenerFn]> = [];\n const raw = Array.isArray(originUndoManager?.eventListeners)\n ? (originUndoManager.eventListeners as unknown[])\n : [];\n for (let i = 0; i + 1 < raw.length; i += 2) {\n const key = String(raw[i]);\n const fn = raw[i + 1] as ListenerFn;\n pairs.push([key, fn]);\n }\n\n const mxLike: Record<string, unknown> & {\n eventListeners: Array<string | ListenerFn>;\n history: unknown[];\n indexOfNextAdd: number;\n _y: Y.UndoManager;\n addListener(name: string, fn: ListenerFn): void;\n fireEvent(evt: unknown): void;\n clear(): void;\n canUndo(): boolean;\n canRedo(): boolean;\n undo(): void;\n redo(): void;\n undoableEditHappened(_edit: unknown): void;\n } = {\n eventListeners: [] as Array<string | ListenerFn>,\n history: [] as unknown[],\n indexOfNextAdd: 0,\n _y: yUndo,\n\n addListener(name: string, fn: ListenerFn) {\n this.eventListeners.push(name, fn);\n },\n\n fireEvent(evt: unknown) {\n const eventName: string =\n (evt as { name?: string } | undefined)?.name ||\n ((evt as { getName?: () => string } | undefined)?.getName?.() ?? \"\");\n for (let i = 0; i + 1 < this.eventListeners.length; i += 2) {\n const key = this.eventListeners[i];\n const listener = this.eventListeners[i + 1] as ListenerFn;\n if (key === eventName) {\n try {\n listener(this, evt);\n } catch (e) {\n console.warn(\"[y-mxgraph] undoManager event listener error:\", e);\n }\n }\n }\n },\n\n clear() {\n if (typeof this._y.clear === \"function\") {\n this._y.clear();\n } else {\n while (this._y.canUndo && this._y.canUndo()) this._y.undo();\n while (this._y.canRedo && this._y.canRedo()) this._y.redo();\n }\n this.history = [];\n this.indexOfNextAdd = 0;\n this.fireEvent(createMxEventObject(\"clear\"));\n },\n\n canUndo(): boolean {\n return typeof this._y.canUndo === \"function\" && this._y.canUndo();\n },\n\n canRedo(): boolean {\n return typeof this._y.canRedo === \"function\" && this._y.canRedo();\n },\n\n undo() {\n this._y.undo();\n },\n\n redo() {\n this._y.redo();\n },\n\n undoableEditHappened() {\n // no-op: 让 yjs 基于事务决定是否入栈\n },\n };\n\n type YUndoEventName = \"stack-item-added\" | \"stack-cleared\" | \"stack-item-popped\" | \"stack-item-updated\";\n const bridgeHandlers: Array<[YUndoEventName, () => void]> = [];\n const bridge = (mxEventName: \"add\" | \"clear\", yEventName: YUndoEventName) => {\n const handler = () => {\n if (mxEventName !== \"clear\" && !lastTxnLocalOrigin) {\n return;\n }\n switch (mxEventName) {\n case \"add\": {\n if (mxLike.indexOfNextAdd < mxLike.history.length) {\n mxLike.history.splice(\n mxLike.indexOfNextAdd,\n mxLike.history.length - mxLike.indexOfNextAdd,\n );\n }\n mxLike.history.push({});\n mxLike.indexOfNextAdd = mxLike.history.length;\n break;\n }\n case \"clear\": {\n mxLike.history = [];\n mxLike.indexOfNextAdd = 0;\n break;\n }\n }\n\n const evt = createMxEventObject(mxEventName, { edit: { changes: [] } });\n mxLike.fireEvent(evt);\n };\n yUndo.on(yEventName, handler);\n bridgeHandlers.push([yEventName, handler]);\n };\n\n bridge(\"add\", \"stack-item-added\");\n bridge(\"clear\", \"stack-cleared\");\n\n const poppedHandler = (e: { type?: string; reason?: string; kind?: string }) => {\n const t = e && (e.type || e.reason || e.kind);\n if (t === \"undo\") {\n if (mxLike.indexOfNextAdd > 0) mxLike.indexOfNextAdd--;\n const evt = createMxEventObject(\"undo\", { edit: { changes: [] } });\n mxLike.fireEvent(evt);\n } else if (t === \"redo\") {\n if (mxLike.indexOfNextAdd < mxLike.history.length)\n mxLike.indexOfNextAdd++;\n const evt = createMxEventObject(\"redo\", { edit: { changes: [] } });\n mxLike.fireEvent(evt);\n }\n };\n yUndo.on(\"stack-item-popped\", poppedHandler);\n\n const updatedHandler = () => {\n const evt = createMxEventObject(\"redo\", { edit: { changes: [] } });\n mxLike.fireEvent(evt);\n };\n yUndo.on(\"stack-item-updated\", updatedHandler);\n\n pairs.forEach(([key, fn]) => {\n const k = key.toLowerCase();\n if (k === \"add\" || k === \"clear\" || k === \"undo\" || k === \"redo\") {\n mxLike.addListener(k, fn);\n }\n });\n\n editor.undoManager = mxLike;\n\n editor.undoListener = function () {\n // no-op in yjs mode\n };\n\n const destroy = () => {\n doc.off(\"beforeTransaction\", beforeTxnHandler);\n doc.off(\"afterTransaction\", afterTxnHandler);\n bridgeHandlers.forEach(([event, handler]) => {\n yUndo.off(event, handler);\n });\n yUndo.off(\"stack-item-popped\", poppedHandler);\n yUndo.off(\"stack-item-updated\", updatedHandler);\n // 恢复原始 undoManager\n editor.undoManager = originUndoManager;\n editor.undoListener = originUndoManager?.undoListener;\n };\n\n return destroy;\n}\n","import { type Awareness } from \"y-protocols/awareness\";\n\nexport function getAwarenessStateValue<T>(\n awareness: Awareness,\n key: string,\n clientId?: string | number\n): T | null {\n const states = awareness.getStates();\n const id = clientId != null ? Number(clientId) : awareness.clientID;\n const clientState = states.get(id as number);\n if (!clientState) return null;\n if (!key) return clientState as T;\n return getByPath(clientState, key) as T | null;\n}\n\nfunction getByPath(obj: unknown, path: string): unknown {\n const parts = path.split(\".\");\n let cur: unknown = obj;\n for (const part of parts) {\n if (cur == null) return null;\n const key: string | number =\n Array.isArray(cur) && /^\\d+$/.test(part) ? Number(part) : part;\n cur = (cur as Record<string, unknown>)?.[key];\n }\n return cur;\n}\n\nexport function setAwarenessStateValue(\n awareness: Awareness,\n key: string,\n value: unknown,\n clientId?: string | number\n): boolean {\n const id = clientId != null ? Number(clientId) : awareness.clientID;\n if (id !== awareness.clientID) return false;\n if (!key) {\n awareness.setLocalState(value as Record<string, unknown>);\n return true;\n }\n const current = (awareness.getLocalState() || {}) as Record<string, unknown>;\n const next = setByPath(current, key, value);\n awareness.setLocalState(next);\n return true;\n}\n\nfunction setByPath(obj: unknown, path: string, value: unknown): Record<string, unknown> {\n const parts = path.split(\".\");\n const root = Array.isArray(obj) ? obj.slice() : { ...(obj as Record<string, unknown>) };\n let cur: Record<string | number, unknown> = root as Record<string | number, unknown>;\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const isIndex = /^\\d+$/.test(part);\n const key: string | number = isIndex ? Number(part) : part;\n const isLast = i === parts.length - 1;\n if (isLast) {\n cur[key] = value;\n } else {\n let next = cur[key];\n const nextIsIndex = /^\\d+$/.test(parts[i + 1]);\n if (next == null) {\n next = nextIsIndex ? [] : {};\n } else {\n next = Array.isArray(next) ? next.slice() : { ...(next as Record<string, unknown>) };\n }\n cur[key] = next;\n cur = next as Record<string | number, unknown>;\n }\n }\n return root as Record<string, unknown>;\n}\n","export function generateColor(seed?: string | number) {\n const hash = hashString(String(seed || Math.random()));\n const h = hash % 360;\n const s = 65 + ((hash >>> 8) % 20);\n const l = 55 + ((hash >>> 16) % 10);\n return hslToHex(h, s, l);\n}\n\nexport function generateRandomName(): string {\n const len = 6;\n const alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n let id = \"\";\n if (\n typeof crypto !== \"undefined\" &&\n typeof (crypto as Crypto).getRandomValues === \"function\"\n ) {\n const bytes = new Uint8Array(len);\n (crypto as Crypto).getRandomValues(bytes);\n for (let i = 0; i < len; i++) {\n id += alphabet[bytes[i] % alphabet.length];\n }\n } else {\n for (let i = 0; i < len; i++) {\n id += alphabet[Math.floor(Math.random() * alphabet.length)];\n }\n }\n return id;\n}\n\nexport function generateRandomId(): string {\n return generateRandomName();\n}\n\nfunction hashString(str: string): number {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = ((hash << 5) + hash) ^ str.charCodeAt(i);\n }\n return hash >>> 0;\n}\n\nfunction hslToHex(h: number, s: number, l: number): string {\n s /= 100;\n l /= 100;\n const c = (1 - Math.abs(2 * l - 1)) * s;\n const hp = h / 60;\n const x = c * (1 - Math.abs((hp % 2) - 1));\n let r1 = 0,\n g1 = 0,\n b1 = 0;\n if (hp >= 0 && hp < 1) [r1, g1, b1] = [c, x, 0];\n else if (hp >= 1 && hp < 2) [r1, g1, b1] = [x, c, 0];\n else if (hp >= 2 && hp < 3) [r1, g1, b1] = [0, c, x];\n else if (hp >= 3 && hp < 4) [r1, g1, b1] = [0, x, c];\n else if (hp >= 4 && hp < 5) [r1, g1, b1] = [x, 0, c];\n else [r1, g1, b1] = [c, 0, x];\n const m = l - c / 2;\n const r = Math.round((r1 + m) * 255);\n const g = Math.round((g1 + m) * 255);\n const b = Math.round((b1 + m) * 255);\n return \"#\" + [r, g, b].map((v) => v.toString(16).padStart(2, \"0\")).join(\"\");\n}\n","export function createCursorImage(color: string) {\n const w = 8;\n const h = 12;\n const path =\n '<path d=\"M 4 0 L 8 12 L 4 10 L 0 12 Z\" stroke=\"' +\n color +\n '\" fill=\"' +\n color +\n '\"/>';\n const svg =\n '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"' +\n w +\n 'px\" height=\"' +\n h +\n 'px\" viewBox=\"0 0 ' +\n w +\n \" \" +\n h +\n '\" version=\"1.1\">' +\n path +\n \"</svg>\";\n const bytes = new Uint8Array(svg.length);\n for (let i = 0; i < svg.length; i++) {\n bytes[i] = svg.charCodeAt(i);\n }\n const encoded = btoa(String.fromCharCode.apply(null, bytes as unknown as number[]));\n return \"data:image/svg+xml;base64,\" + encoded;\n}\n","import { throttle } from \"lodash-es\";\nimport { colord } from \"colord\";\nimport { createCursorImage } from \"../../helper/cursor\";\n\nimport { type Awareness } from \"y-protocols/awareness\";\nimport { type RemoteCursor } from \"./index\";\nimport type { DrawioFile, MxGraph } from \"../../types/drawio\";\n\nexport const CacheKey = \"__remoteCursor__\";\n\nfunction createCursorEl(color: string, username: string) {\n const cursor = document.createElement(\"div\");\n cursor.style.position = \"absolute\";\n cursor.style.opacity = \"0.9\";\n cursor.style.transition = \"all 0.3s ease-in-out\";\n\n const img = document.createElement(\"img\");\n img.style.transform = \"rotate(-45deg) translateX(-14px)\";\n img.setAttribute(\"src\", createCursorImage(color));\n img.style.width = \"10px\";\n img.style.transition = \"all 0.3s ease-in-out\";\n cursor.appendChild(img);\n\n const name = document.createElement(\"div\");\n name.style.backgroundColor = color;\n name.style.color = colord(color).isDark() ? \"#fff\" : \"#000\";\n name.style.fontSize = \"9pt\";\n name.style.padding = \"3px 7px\";\n name.style.marginTop = \"8px\";\n name.style.borderRadius = \"10px\";\n name.style.maxWidth = \"100px\";\n name.style.overflow = \"hidden\";\n name.style.textOverflow = \"ellipsis\";\n name.style.whiteSpace = \"nowrap\";\n\n name.innerText = username;\n cursor.appendChild(name);\n return cursor;\n}\n\nexport function bindCursor(\n file: DrawioFile,\n options: {\n awareness: Awareness;\n graph?: MxGraph;\n mouseMoveThrottle?: number;\n },\n) {\n const graph = options.graph || file.getUi().editor.graph;\n const awareness = options.awareness;\n const mouseMoveThrottle = options.mouseMoveThrottle ?? 100;\n\n const listener = {\n startX: 0,\n startY: 0,\n scrollLeft: 0,\n scrollTop: 0,\n mouseDown: function () {},\n mouseUp: function () {},\n mouseMove: throttle(function (\n _sender: unknown,\n event: { graphX: number; graphY: number; evt: MouseEvent },\n ) {\n const containerRect = graph.container.getBoundingClientRect();\n const { translate, scale } = graph.view;\n\n const x = Math.round(\n (event.evt.clientX - containerRect.x + graph.container.scrollLeft) /\n scale -\n translate.x,\n );\n const y = Math.round(\n (event.evt.clientY - containerRect.y + graph.container.scrollTop) /\n scale -\n translate.y,\n );\n\n awareness.setLocalStateField(\"cursor\", {\n x,\n y,\n pageId: file.getUi().currentPage?.getId(),\n });\n }, mouseMoveThrottle),\n };\n\n graph.addMouseListener(listener);\n\n // 鼠标离开画布时隐藏光标\n const handleMouseLeave = () => {\n awareness.setLocalStateField(\"cursor\", {\n x: 0,\n y: 0,\n pageId: file.getUi().currentPage?.getId(),\n hide: true,\n });\n };\n graph.container.addEventListener(\"mouseleave\", handleMouseLeave);\n\n return () => {\n graph.removeMouseListener(listener);\n graph.container.removeEventListener(\"mouseleave\", handleMouseLeave);\n };\n}\n\nexport function renderRemoteCursors(\n ui: { editor: { graph: MxGraph }; currentPage?: { getId(): string } | null; diagramContainer: HTMLElement },\n remotes: Map<number, RemoteCursor>,\n) {\n if (!(CacheKey in ui)) {\n (ui as Record<string, unknown>)[CacheKey] = new Map<number, HTMLDivElement>();\n }\n\n const cache = (ui as Record<string, unknown>)[CacheKey] as Map<number, HTMLDivElement>;\n const currentPageId = ui.currentPage?.getId();\n\n if (!currentPageId) {\n Array.from(cache.values()).forEach((el) => el.remove());\n cache.clear();\n return;\n }\n\n const currentPageRemotes: RemoteCursor[] = [];\n const otherPageRemotes: RemoteCursor[] = [];\n const leaveRemotesIds = new Set<number>();\n\n Array.from(cache.keys()).forEach((clientId) => {\n if (!remotes.has(clientId)) leaveRemotesIds.add(clientId);\n });\n\n Array.from(remotes.values()).forEach((remote) => {\n if (remote.cursorState?.pageId === currentPageId) {\n currentPageRemotes.push(remote);\n } else {\n otherPageRemotes.push(remote);\n }\n });\n\n leaveRemotesIds.forEach((clientId) => {\n const el = cache.get(clientId);\n cache.delete(clientId);\n if (!el) return;\n el.remove();\n });\n\n otherPageRemotes.forEach(({ clientId }) => {\n const el = cache.get(clientId);\n if (!el) return;\n el.remove();\n });\n\n if (!currentPageRemotes.length) return;\n\n const graph = ui.editor.graph;\n const { translate, scale } = graph.view;\n\n currentPageRemotes.forEach(\n ({ clientId, cursorState, userColor, userName }) => {\n if (!cursorState) return;\n let el = cache.get(clientId);\n\n // 隐藏状态:移除光标元素\n if (cursorState.hide) {\n if (el) {\n el.remove();\n cache.delete(clientId);\n }\n return;\n }\n\n if (!el) {\n el = createCursorEl(userColor, userName);\n ui.diagramContainer.appendChild(el);\n cache.set(clientId, el);\n }\n\n const x = (translate.x + cursorState.x) * scale + 8;\n const y = (translate.y + cursorState.y) * scale - 12;\n\n const cx = Math.max(\n graph.container.scrollLeft,\n Math.min(\n graph.container.scrollLeft +\n graph.container.clientWidth -\n el.clientWidth,\n x,\n ),\n );\n\n const cy = Math.max(\n graph.container.scrollTop - 22,\n Math.min(\n graph.container.scrollTop +\n graph.container.clientHeight -\n el.clientHeight,\n y,\n ),\n );\n el.style.left = cx + \"px\";\n el.style.top = cy + \"px\";\n el.style.display = \"\";\n },\n );\n}\n","export function getId(item: { id?: string | number }) {\n if (item.id) return item.id;\n return null;\n}\n","import { type Awareness } from \"y-protocols/awareness\";\nimport { getId } from \"../../helper/getId\";\nimport { type RemoteCursor } from \"./index\";\nimport type { DrawioFile, MxGraph } from \"../../types/drawio\";\n\nexport const SELECTION_OPACITY = 70;\nexport const CacheKey = \"__remoteSelection__\";\n\nexport function bindSelection(\n file: DrawioFile,\n options: { awareness: Awareness; graph?: MxGraph },\n) {\n const graph = options.graph || file.getUi().editor.graph;\n const awareness = options.awareness;\n\n const handler = function () {\n const pageId = file.getUi().currentPage?.getId();\n const cells = graph.getSelectionModel().cells as Record<string, unknown>;\n const ids = Object.keys(cells || {})\n .map(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (key) => getId(cells[key] as any) as string,\n )\n .filter(Boolean);\n awareness.setLocalStateField(\"selection\", { ids, pageId });\n };\n\n const selectionModel = graph.getSelectionModel();\n selectionModel.addListener(\"change\", handler);\n\n return () => {\n selectionModel.removeListener(\"change\", handler);\n };\n}\n\nexport function renderRemoteSelections(\n ui: { editor: { graph: MxGraph }; currentPage?: { getId(): string } | null },\n remotes: Map<number, RemoteCursor>,\n) {\n if (!(CacheKey in ui)) {\n (ui as Record<string, unknown>)[CacheKey] = new Map<\n number,\n Map<string, { destroy: () => void }>\n >();\n }\n\n const cache = (ui as Record<string, unknown>)[CacheKey] as Map<\n number,\n Map<string, { destroy: () => void }>\n >;\n\n const currentPageId = ui.currentPage?.getId();\n\n if (!currentPageId) {\n cache.clear();\n return;\n }\n\n const currentPageRemotes: RemoteCursor[] = [];\n const otherPageRemotes: RemoteCursor[] = [];\n const leaveRemotesIds = new Set<number>();\n\n Array.from(cache.keys()).forEach((clientId) => {\n if (!remotes.has(clientId)) leaveRemotesIds.add(clientId);\n });\n\n Array.from(remotes.values()).forEach((remote) => {\n if (remote.selectionState?.pageId === currentPageId) {\n currentPageRemotes.push(remote);\n } else {\n otherPageRemotes.push(remote);\n }\n });\n\n leaveRemotesIds.forEach((clientId) => {\n const highlightCellMap = cache.get(clientId);\n cache.delete(clientId);\n if (!highlightCellMap) return;\n Array.from(highlightCellMap.values()).forEach((h) => h.destroy());\n highlightCellMap.clear();\n });\n\n otherPageRemotes.forEach(({ clientId }) => {\n const highlightCellMap = cache.get(clientId);\n if (!highlightCellMap) return;\n Array.from(highlightCellMap.values()).forEach((h) => h.destroy());\n highlightCellMap.clear();\n });\n\n if (!currentPageRemotes.length) return;\n\n const graph = ui.editor.graph;\n\n currentPageRemotes.forEach(({ clientId, selectionState, userColor }) => {\n let highlightCellMap = cache.get(clientId);\n if (!highlightCellMap) {\n highlightCellMap = new Map<string, { destroy: () => void }>();\n cache.set(clientId, highlightCellMap);\n }\n\n const currentIds = new Set<string>(selectionState?.ids ?? []);\n\n // 移除不再选中的高亮\n Array.from(highlightCellMap.keys()).forEach((id) => {\n if (!currentIds.has(id)) {\n highlightCellMap.get(id)?.destroy();\n highlightCellMap.delete(id);\n }\n });\n\n // 添加新选中的高亮\n currentIds.forEach((id) => {\n if (highlightCellMap.has(id)) return;\n const cell = graph.model.getCell(id);\n if (cell) {\n const highlightCell = graph.highlightCell(\n cell,\n userColor,\n 60000,\n SELECTION_OPACITY,\n 3,\n );\n highlightCellMap.set(id, highlightCell);\n }\n });\n });\n}\n","import { type Awareness } from \"y-protocols/awareness\";\nimport {\n getAwarenessStateValue,\n setAwarenessStateValue,\n} from \"../../helper/awarenessStateValue\";\nimport { generateColor, generateRandomName } from \"../../helper/random\";\nimport { bindCursor, renderRemoteCursors } from \"./cursor\";\nimport { bindSelection, renderRemoteSelections } from \"./selection\";\nimport type { DrawioFile, MxGraph } from \"../../types/drawio\";\n\nexport const DEFAULT_USER_NAME_KEY = \"user.name\";\nexport const DEFAULT_USER_COLOR_KEY = \"user.color\";\n\ntype CursorState = {\n x: number;\n y: number;\n pageId?: string | null;\n hide?: boolean;\n};\n\ntype SelectionState = {\n ids: string[];\n pageId?: string | null;\n};\n\nexport type RemoteCursor = {\n clientId: number;\n cursorState: CursorState | null;\n selectionState: SelectionState | null;\n userColor: string;\n userName: string;\n};\n\nexport function bindCollaborator(\n file: DrawioFile,\n options: {\n awareness: Awareness;\n graph?: MxGraph;\n cursor?: boolean | { userNameKey?: string; userColorKey?: string };\n mouseMoveThrottle?: number;\n },\n) {\n const graph = options.graph || file.getUi().editor.graph;\n const awareness = options.awareness;\n const mouseMoveThrottle = options.mouseMoveThrottle ?? 100;\n\n const cursorOption = options.cursor;\n const userNameKey =\n typeof cursorOption === \"object\" && cursorOption?.userNameKey\n ? cursorOption.userNameKey\n : DEFAULT_USER_NAME_KEY;\n const userColorKey =\n typeof cursorOption === \"object\" && cursorOption?.userColorKey\n ? cursorOption.userColorKey\n : DEFAULT_USER_COLOR_KEY;\n\n let userName = getAwarenessStateValue<string>(awareness, userNameKey);\n if (!userName) {\n userName = generateRandomName();\n setAwarenessStateValue(awareness, userNameKey, userName);\n }\n let userColor = getAwarenessStateValue<string>(awareness, userColorKey);\n if (!userColor) {\n userColor = generateColor(userName);\n setAwarenessStateValue(awareness, userColorKey, userColor);\n }\n\n const cleanupCursor = bindCursor(file, {\n awareness,\n graph,\n mouseMoveThrottle,\n });\n const cleanupSelection = bindSelection(file, {\n awareness,\n graph,\n });\n\n const showCursor = options.cursor ?? true;\n let cleanupAwareness: (() => void) | undefined;\n\n if (typeof showCursor === \"boolean\" && showCursor) {\n const awarenessHandler = (update: {\n added: number[];\n removed: number[];\n updated: number[];\n }) => {\n const states = awareness.getStates();\n const remotes = new Map<number, RemoteCursor>();\n\n const changedClientIds = new Set([...update.added, ...update.updated]);\n for (const [clientId] of states.entries()) {\n if (clientId === awareness.clientID) continue;\n if (!changedClientIds.has(clientId)) continue;\n\n const name =\n getAwarenessStateValue<string>(awareness, userNameKey, clientId) ||\n clientId + \"\";\n const color =\n getAwarenessStateValue<string>(awareness, userColorKey, clientId) ||\n \"#000000\";\n\n remotes.set(clientId, {\n clientId,\n cursorState: getAwarenessStateValue<CursorState>(\n awareness,\n \"cursor\",\n clientId,\n ),\n selectionState: getAwarenessStateValue<SelectionState>(\n awareness,\n \"selection\",\n clientId,\n ),\n userColor: color,\n userName: name,\n });\n }\n\n renderRemoteCursors(file.getUi(), remotes);\n renderRemoteSelections(file.getUi(), remotes);\n };\n awareness.on(\"update\", awarenessHandler);\n cleanupAwareness = () => awareness.off(\"update\", awarenessHandler);\n }\n\n return () => {\n cleanupCursor?.();\n cleanupSelection?.();\n cleanupAwareness?.();\n };\n}\n","import * as Y from \"yjs\";\nimport { type Awareness } from \"y-protocols/awareness\";\nimport { applyFilePatch, generatePatch, initDocSnapshot } from \"./patch\";\nimport { xml2doc, doc2xml } from \"../transformer\";\nimport { bindUndoManager } from \"./undoManager\";\nimport { bindCollaborator } from \"./collaborator\";\nimport { LOCAL_ORIGIN } from \"../helper/origin\";\nimport {\n key as mxfileKey,\n diagramOrderKey,\n type YMxFile,\n} from \"../models/mxfile\";\nimport {\n key as diagramKey,\n parse as parseDiagram,\n type YDiagram,\n} from \"../models/diagram\";\nimport { parse as parseXml } from \"../helper/xml\";\nimport type { DrawioFile, MxGraphModel } from \"../types/drawio\";\n\n/**\n * 控制 Binding 构造时 file 与 Y.Doc 的初始内容对齐策略。\n * - `replace` : doc 非空则用 doc 覆盖 file;doc 为空则保留 file 现有数据(默认)。\n * - `merge-remote` : 按 diagram id 取并集,同 id 冲突时以 doc 为准(远端权威)。\n * - `merge-client` : 按 diagram id 取并集,同 id 冲突时以 file 为准(本地权威,覆盖到 doc)。\n */\nexport type InitialContentStrategy =\n | \"replace\"\n | \"merge-remote\"\n | \"merge-client\";\n\nexport interface BindDrawioFileOptions {\n doc: Y.Doc;\n awareness?: Awareness;\n undoManager?: Y.UndoManager;\n mouseMoveThrottle?: number;\n cursor?:\n | boolean\n | {\n userNameKey?: string;\n userColorKey?: string;\n };\n /**\n * 初始内容对齐策略,默认 `replace`。详见 {@link InitialContentStrategy}。\n */\n initialContent?: InitialContentStrategy;\n /**\n * 自定义把 XML 应用到 file 的方式。默认实现只调用\n * `file.ui.setFileData(xml)`(刷新 UI / 重建 pages),\n * **不会**调用 `file.setData(xml)`,以避免把 file 标记为「已修改」\n * 触发 draw.io 的 \"Save diagrams to:\" 存储选择对话框。\n *\n * 若业务方确实需要同步 `file.data`(如自定义 CollabFile 或依赖\n * `file.save()`),可提供自定义实现。\n */\n applyFileData?: (file: DrawioFile, xml: string) => void;\n}\n\n/**\n * 默认只调用 `file.ui.setFileData(xml)` 重建 UI(pages / mxGraphModel),\n * 有意跳过 `file.setData(xml)`:在 Yjs 驱动的协作场景下,`file.data`\n * 不是真实状态来源;调用 `setData` 会把文件标记为「已修改」,\n * draw.io 在没有配置存储后端时会弹出 \"Save diagrams to:\" 存储选择对话框。\n *\n * 若业务方确实需要同步 `file.data`(例如需要 `file.save()` 或依赖\n * `file.data` 的快照逻辑),可通过 `applyFileData` 选项覆写:\n *\n * ```ts\n * new Binding(file, {\n * doc,\n * applyFileData: (f, xml) => {\n * f.ui.setFileData(xml);\n * f.setData(xml);\n * },\n * });\n * ```\n */\nconst defaultApplyFileData = (file: DrawioFile, xml: string) => {\n file.ui.setFileData(xml);\n};\n\n/**\n * 把 file XML 中的 diagram 合并进 Y.Doc。仅在 merge 策略 + doc 已有数据时调用。\n * @returns 是否成功合并;解析失败时返回 false 由调用方回退到 replace。\n */\nfunction mergeFileIntoDoc(\n doc: Y.Doc,\n fileXml: string,\n strategy: \"merge-remote\" | \"merge-client\",\n): boolean {\n let parsed: unknown;\n try {\n parsed = parseXml(fileXml);\n } catch (err) {\n console.warn(\n \"[y-mxgraph] 合并失败,file XML 解析异常,回退到 replace:\",\n err,\n );\n return false;\n }\n\n const mxfileObj = (parsed as Record<string, unknown>)?.mxfile as\n | { diagram?: Array<Record<string, unknown>> }\n | undefined;\n if (!mxfileObj || !Array.isArray(mxfileObj.diagram)) {\n console.warn(\n \"[y-mxgraph] 合并失败,file XML 不是合法 mxfile,回退到 replace\",\n );\n return false;\n }\n\n const mxfileMap = doc.getMap(mxfileKey);\n const diagramMap = mxfileMap.get(diagramKey) as Y.Map<YDiagram> | undefined;\n const diagramOrder = mxfileMap.get(diagramOrderKey) as\n | Y.Array<string>\n | undefined;\n if (!diagramMap || !diagramOrder) {\n console.warn(\"[y-mxgraph] 合并失败,doc 结构不完整,回退到 replace\");\n return false;\n }\n\n doc.transact(() => {\n for (const diagram of mxfileObj.diagram!) {\n const id =\n ((diagram as { _attributes?: { id?: string } })._attributes\n ?.id as string) || \"\";\n if (!id) continue;\n\n const docHas = diagramMap.has(id);\n if (docHas && strategy === \"merge-remote\") {\n // doc 优先,跳过\n continue;\n }\n\n // 覆盖或新增\n const yDiagram = parseDiagram(\n diagram as unknown as import(\"../models/diagram\").Diagram,\n );\n diagramMap.set(id, yDiagram);\n if (!docHas) {\n diagramOrder.push([id]);\n }\n }\n });\n return true;\n}\n\nfunction reconcileInitialContent(\n doc: Y.Doc,\n file: DrawioFile,\n strategy: InitialContentStrategy,\n applyFileData: (file: DrawioFile, xml: string) => void,\n): boolean {\n const mxfileMap = doc.getMap(mxfileKey);\n const docHasData = mxfileMap.size > 0;\n // 与旧 demo 行为保持一致:file 是否「有任何数据」用 truthy 判断;\n // 只有完全空时才注入模板,避免把 draw.io 默认文件覆盖成模板触发\n // 「Save diagrams to:」存储选择对话框。\n const fileHasAnyData = !!file.data;\n // merge 策略需要进一步判断是否存在真实 diagram 内容\n const fileHasDiagrams = fileHasAnyData && file.data.includes(\"<diagram\");\n\n if (strategy === \"replace\") {\n if (docHasData) {\n const xml = doc2xml(doc);\n if (xml && xml.includes(\"<diagram\")) {\n applyFileData(file, xml);\n } else if (!fileHasAnyData) {\n applyFileData(file, Binding.generateFileTemplate(\"diagram-0\"));\n }\n } else if (!fileHasAnyData) {\n applyFileData(file, Binding.generateFileTemplate(\"diagram-0\"));\n }\n // 其余情况保留 file,避免触发 draw.io 默认文件的存储对话框\n return mxfileMap.size > 0;\n }\n\n // merge-remote / merge-client\n if (!docHasData && !fileHasDiagrams) {\n if (!fileHasAnyData) {\n applyFileData(file, Binding.generateFileTemplate(\"diagram-0\"));\n }\n return false;\n }\n\n if (!docHasData && fileHasDiagrams) {\n // 仅 file 有 → 把 file 写入 doc,file 保持不变\n try {\n doc.transact(() => {\n xml2doc(file.data, doc);\n });\n return true;\n } catch (err) {\n console.warn(\n \"[y-mxgraph] merge 模式下 xml2doc 失败,回退 replace:\",\n err,\n );\n applyFileData(file, Binding.generateFileTemplate(\"diagram-0\"));\n return false;\n }\n }\n\n if (docHasData && !fileHasDiagrams) {\n // 仅 doc 有可用 diagram → 用 doc 覆盖 file\n const xml = doc2xml(doc);\n if (xml && xml.includes(\"<diagram\")) {\n applyFileData(file, xml);\n } else if (!fileHasAnyData) {\n applyFileData(file, Binding.generateFileTemplate(\"diagram-0\"));\n }\n return mxfileMap.size > 0;\n }\n\n // 双方都有可用 diagram → 按策略合并\n const ok = mergeFileIntoDoc(doc, file.data, strategy);\n if (!ok) {\n // 解析失败回退到 replace(用 doc 覆盖 file)\n const xml = doc2xml(doc);\n if (xml && xml.includes(\"<diagram\")) applyFileData(file, xml);\n return mxfileMap.size > 0;\n }\n const xml = doc2xml(doc);\n if (xml && xml.includes(\"<diagram\")) applyFileData(file, xml);\n return true;\n}\n\n/**\n * Y-MXGraph 绑定类,管理 draw.io 文件与 Y.Doc 的双向同步\n *\n * 初始化流程对齐 y-prosemirror 等数据源:\n * - 绑定时不向 Y.Doc 写入初始数据\n * - 在第一次本地编辑时才初始化 Y.Doc\n * - 新客户端加入时,同步已有的远端数据到本地\n */\nexport class Binding {\n /** Y.Doc 实例,用于协同数据存储 */\n readonly doc: Y.Doc;\n /** mxGraph 的数据模型,用于监听本地变更 */\n private mxGraphModel: MxGraphModel;\n /** 本地变更抑制标志,防止循环同步 */\n private suppressLocalApply = false;\n /** 初始化标志,标记 Y.Doc 是否已初始化 */\n private docInitialized = false;\n /** mxGraph change 事件监听器 */\n private mxListener: () => void;\n /** Yjs 文档深度变更监听器 */\n private docObserver: (\n events: Y.YEvent<\n Y.XmlElement | Y.Array<string> | Y.Map<Y.XmlElement> | YMxFile\n >[],\n transaction: Y.Transaction,\n ) => void;\n /** 协作功能清理函数(awareness 光标/选区) */\n private cleanupCollaborator?: () => void;\n /** UndoManager 绑定清理函数 */\n private cleanupUndoManager?: () => void;\n /** 初始内容策略 */\n private initialContentStrategy: InitialContentStrategy;\n\n /** replace 策略下,构造时 doc 为空,现在 doc 有数据时需要强制替换 */\n private get shouldReplaceWhenDocHasData(): boolean {\n return this.initialContentStrategy === \"replace\" && !this.docInitialized;\n }\n\n constructor(file: DrawioFile, options: BindDrawioFileOptions) {\n const {\n doc,\n awareness,\n undoManager,\n mouseMoveThrottle,\n cursor,\n initialContent = \"replace\",\n applyFileData = defaultApplyFileData,\n } = options;\n\n this.doc = doc;\n this.initialContentStrategy = initialContent;\n\n const ui = file.getUi();\n const graph = ui.editor.graph;\n this.mxGraphModel = graph.model;\n\n // 统一初始化:根据 initialContent 策略对齐 file 与 doc。\n // 内部会调用 applyFileData 钩子(默认 ui.setFileData + file.setData),\n // 业务方不再需要在外部手动同步。\n this.suppressLocalApply = true;\n try {\n this.docInitialized = reconcileInitialContent(\n doc,\n file,\n initialContent,\n applyFileData,\n );\n // doc 在 reconcile 后才确定有内容,需建立 snapshot 基线\n if (this.docInitialized) {\n initDocSnapshot(doc, false);\n }\n } finally {\n this.suppressLocalApply = false;\n }\n\n // 对齐 shadowPages(reconcile 可能已经替换了 ui.pages)\n file.setShadowPages(file.ui.clonePages(file.ui.pages));\n\n // 本地变更监听\n this.mxListener = () => {\n if (this.suppressLocalApply) return;\n\n const patch = file.ui.diffPages(\n file.shadowPages,\n file.ui.pages,\n ) as import(\"./patch\").FilePatch;\n const patchKeys = Object.keys(patch);\n\n // 没有实际本地变更时直接跳过\n if (patchKeys.length === 0) return;\n\n // 第一次有实际本地编辑时才初始化 Y.Doc\n if (!this.docInitialized) {\n doc.transact(() => {\n xml2doc(file.data, doc);\n initDocSnapshot(doc, false);\n });\n this.docInitialized = true;\n }\n\n file.setShadowPages(file.ui.clonePages(file.ui.pages));\n applyFilePatch(doc, patch, { origin: LOCAL_ORIGIN });\n };\n this.mxGraphModel.addListener(\"change\", this.mxListener);\n\n // 远端变更监听\n this.docObserver = (\n events: Y.YEvent<\n Y.XmlElement | Y.Array<string> | Y.Map<Y.XmlElement> | YMxFile\n >[],\n transaction: Y.Transaction,\n ) => {\n if (transaction.local && transaction.origin === LOCAL_ORIGIN) {\n generatePatch(events);\n return;\n }\n\n // replace 策略下,若构造时 doc 为空,现在 doc 有数据,强制替换本地 file\n // 注意:只有非本地 transaction 时才执行强制替换,避免本地初始化时自我覆盖\n if (this.shouldReplaceWhenDocHasData && !transaction.local) {\n const mxfileMap = doc.getMap(mxfileKey);\n const diagramMap = mxfileMap.get(diagramKey) as Y.Map<Y.XmlElement> | undefined;\n if (diagramMap && diagramMap.size > 0) {\n // doc 已有数据,执行强制替换\n const xml = doc2xml(doc);\n if (xml && xml.includes(\"<diagram\")) {\n this.suppressLocalApply = true;\n try {\n applyFileData(file, xml);\n file.setShadowPages(file.ui.clonePages(file.ui.pages));\n initDocSnapshot(doc, false);\n // 重置 editor 状态,避免显示 modified 标记\n const ui = file.getUi();\n const editor = ui.editor as unknown as { setStatus: (status: string) => void; setModified: (modified: boolean) => void };\n editor.setStatus(\"\");\n editor.setModified(false);\n } finally {\n this.suppressLocalApply = false;\n }\n // 强制替换完成后再标记 docInitialized\n this.docInitialized = true;\n return;\n }\n }\n }\n\n // 标记已初始化(远端数据到达且不是首次强制替换)\n if (!this.docInitialized) {\n this.docInitialized = true;\n }\n\n const patch = generatePatch(events);\n if (Object.keys(patch).length === 0) return;\n this.suppressLocalApply = true;\n try {\n file.patch([patch]);\n file.setShadowPages(file.ui.clonePages(file.ui.pages));\n } finally {\n this.suppressLocalApply = false;\n }\n };\n doc.getMap(mxfileKey).observeDeep(this.docObserver);\n\n // 协作功能\n if (awareness) {\n this.cleanupCollaborator = bindCollaborator(file, {\n awareness,\n graph,\n cursor: cursor ?? true,\n mouseMoveThrottle,\n });\n }\n\n // UndoManager\n if (undoManager) {\n this.cleanupUndoManager = bindUndoManager(doc, file, undoManager);\n }\n }\n\n /**\n * 销毁绑定,解除所有监听器\n * @param deep - 是否深度清理(包括 awareness/undoManager),默认 false\n */\n destroy(deep = false): void {\n this.mxGraphModel.removeListener(\"change\", this.mxListener);\n this.doc.getMap(mxfileKey).unobserveDeep(this.docObserver);\n if (deep) {\n this.cleanupCollaborator?.();\n this.cleanupUndoManager?.();\n }\n }\n\n /**\n * 生成标准化的 mxfile XML 模板,用于确保多端协同的数据起点一致。\n *\n * draw.io 每次新建 diagram 时默认生成随机 id(如 `DEMOabHTdChjKBf1yHdD`)。\n * 如果各客户端初始化时的 diagram id 不同,Y.Doc 中的数据与本地 file.data 无法对齐,\n * 会导致:\n * - 后进房间的客户端出现「孤立 page」(来自本地 XML,未写入 Y.Doc)\n * - patch 的 diff 无法正确匹配 diagram/cell id,协同失效\n *\n * 因此业务方应在初始化 draw.io 文件时,先用此方法生成统一起点的 XML,\n * 再注入到 draw.io 的 currentFile 中(详见文档「接入注意事项」)。\n *\n * @param diagramId - diagram 的固定 id,默认 `diagram-0`\n * @returns 最小化的 mxfile XML 字符串\n */\n static generateFileTemplate(diagramId = \"diagram-0\"): string {\n return `<mxfile pages=\"1\">\n <diagram id=\"${diagramId}\">\n <mxGraphModel>\n <root>\n <mxCell id=\"0\" />\n <mxCell id=\"1\" parent=\"0\" />\n </root>\n </mxGraphModel>\n </diagram>\n</mxfile>`;\n }\n\n /**\n * 静态工厂方法,创建 Binding 实例\n * 与 `new Binding()` 等价\n */\n static create(file: DrawioFile, options: BindDrawioFileOptions): Binding {\n return new Binding(file, options);\n }\n}\n"],"names":["key","parse","xml2js","serializer","js2xml","Y","serialize","mxCellKey","parseMxCell","serializeMxCell","parseMxGraphModel","mxGraphModelKey","serializeMxGraphModel","diagramKey","parseDiagram","_a","serializeDiagram","mxfileKey","id","orderArr","xmlSerializer","parseMxFile","serializerMxFile","serializerMxGraphModel","CacheKey","colord","throttle","parseXml","xml","ui"],"mappings":"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"}
|