y-mxgraph 0.5.8 → 0.6.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sources":["../../../iframe-bridge/src/origin.ts","../../../iframe-bridge/src/server.ts"],"sourcesContent":["/**\n * iframe bridge 内部变更的 origin 标识。\n * 当 provider 端产生 ydoc-update 时,使用此 origin 标记,\n * 以便 server 端的 UndoManager 能正确追踪来自 iframe 的变更。\n */\nexport const IFRAME_ORIGIN: object = {};\n\n/**\n * 基线数据标记(用于首次初始化)。\n * 此 origin 的更新不应进入 UndoManager 的撤销栈。\n */\nexport const BASELINE_ORIGIN: object = {};\n","import * as Y from \"yjs\";\nimport {\n Awareness,\n applyAwarenessUpdate,\n encodeAwarenessUpdate,\n} from \"y-protocols/awareness\";\nimport { IFRAME_ORIGIN, BASELINE_ORIGIN } from \"./origin.js\";\n\nexport interface IframeBridgeServerOptions {\n undoManager?: Y.UndoManager;\n}\n\nexport interface IframeBridgeServer {\n destroy: () => void;\n}\n\nexport function createIframeBridgeServer(\n iframe: HTMLIFrameElement,\n ydoc: Y.Doc,\n awareness: Awareness,\n options?: IframeBridgeServerOptions,\n): IframeBridgeServer {\n const { undoManager } = options ?? {};\n let iframeReady = false;\n let applyingIframeUpdate = false;\n\n function postToIframe(type: string, payload?: Uint8Array) {\n const cw = iframe.contentWindow;\n if (cw) {\n cw.postMessage({ type, payload: payload ? Array.from(payload) : [] }, \"*\");\n }\n }\n\n function postUndoStateToIframe() {\n if (!undoManager) return;\n const undoStack = (undoManager as any).undoStack;\n const redoStack = (undoManager as any).redoStack;\n const cw = iframe.contentWindow;\n if (cw) {\n const state = {\n type: \"undo-state\",\n canUndo: undoManager.canUndo(),\n canRedo: undoManager.canRedo(),\n undoStackSize: undoStack?.length ?? 0,\n redoStackSize: redoStack?.length ?? 0,\n };\n cw.postMessage(state, \"*\");\n }\n }\n\n const onYdocUpdate = (update: Uint8Array, origin: unknown) => {\n if (origin === IFRAME_ORIGIN) return;\n postToIframe(\"ydoc-update\", update);\n };\n\n const onAwarenessUpdate = ({\n added,\n updated,\n removed,\n }: {\n added: number[];\n updated: number[];\n removed: number[];\n }) => {\n if (applyingIframeUpdate) return;\n const changes = [...added, ...updated, ...removed];\n if (changes.length === 0) return;\n\n // 把所有变化的 clientID 都发送给 iframe(包括其他 Webrtc peers 的光标更新)\n // 但要注意:server 自身的 clientID 需要被 iframe 识别为 serverClientId\n const update = encodeAwarenessUpdate(awareness, changes);\n postToIframe(\"awareness-update\", update);\n };\n\n const onMessage = (event: MessageEvent) => {\n if (event.source !== iframe.contentWindow) return;\n\n const { type: msgType, payload } = event.data;\n\n if (msgType === \"init\") {\n if (!iframeReady) {\n iframeReady = true;\n }\n const docState = Y.encodeStateAsUpdate(ydoc);\n const awarenessState = encodeAwarenessUpdate(\n awareness,\n Array.from(awareness.getStates().keys()),\n );\n postToIframe(\"ydoc-sync\", new Uint8Array(Array.from(docState)));\n // 在单独的 postMessage 中发送 serverClientId,方便 iframe 接收\n const cw = iframe.contentWindow;\n if (cw) {\n cw.postMessage(\n { type: \"awareness-sync\", payload: Array.from(awarenessState), serverClientId: awareness.clientID },\n \"*\",\n );\n }\n // 同步初始 undo 状态\n postUndoStateToIframe();\n } else if (msgType === \"ping\") {\n const cw = iframe.contentWindow;\n if (cw) {\n cw.postMessage(\n { type: \"pong\", serverClientId: awareness.clientID },\n \"*\",\n );\n }\n } else if (msgType === \"ydoc-update\") {\n const update = new Uint8Array(payload);\n const isBaseline = event.data.isBaseline;\n // 基线数据使用 BASELINE_ORIGIN(不进入 undo 栈),编辑数据使用 IFRAME_ORIGIN\n const applyOrigin = isBaseline ? BASELINE_ORIGIN : IFRAME_ORIGIN;\n Y.applyUpdate(ydoc, update, applyOrigin);\n // 源 iframe 已经持有此 update,无需回传\n } else if (msgType === \"awareness-update\") {\n // 应用 iframe 的 awareness 更新时设置标志,防止触发 onAwarenessUpdate 回传\n applyingIframeUpdate = true;\n applyAwarenessUpdate(awareness, new Uint8Array(payload), IFRAME_ORIGIN);\n applyingIframeUpdate = false;\n } else if (msgType === \"undo\" && undoManager) {\n undoManager.undo();\n postUndoStateToIframe();\n } else if (msgType === \"redo\" && undoManager) {\n undoManager.redo();\n postUndoStateToIframe();\n }\n };\n\n const onUndoPopped = () => {\n postUndoStateToIframe();\n };\n\n const onStackCleared = () => {\n postUndoStateToIframe();\n };\n\n const onStackItemAdded = () => {\n postUndoStateToIframe();\n };\n\n ydoc.on(\"update\", onYdocUpdate);\n awareness.on(\"update\", onAwarenessUpdate);\n window.addEventListener(\"message\", onMessage);\n if (undoManager) {\n undoManager.on(\"stack-item-popped\", onUndoPopped);\n undoManager.on(\"stack-cleared\", onStackCleared);\n undoManager.on(\"stack-item-added\", onStackItemAdded);\n }\n\n return {\n destroy: () => {\n ydoc.off(\"update\", onYdocUpdate);\n awareness.off(\"update\", onAwarenessUpdate);\n window.removeEventListener(\"message\", onMessage);\n if (undoManager) {\n undoManager.off(\"stack-item-popped\", onUndoPopped);\n undoManager.off(\"stack-cleared\", onStackCleared);\n undoManager.off(\"stack-item-added\", onStackItemAdded);\n }\n iframeReady = false;\n },\n };\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sources":["../../../iframe-bridge/src/origin.ts","../../../iframe-bridge/src/server.ts"],"sourcesContent":["/**\n * iframe bridge 内部变更的 origin 标识。\n * 当 provider 端产生 ydoc-update 时,使用此 origin 标记,\n * 以便 server 端的 UndoManager 能正确追踪来自 iframe 的变更。\n */\nexport const IFRAME_ORIGIN: object = {};\n\n/**\n * 基线数据标记(用于首次初始化)。\n * 此 origin 的更新不应进入 UndoManager 的撤销栈。\n */\nexport const BASELINE_ORIGIN: object = {};\n","import * as Y from \"yjs\";\nimport {\n Awareness,\n applyAwarenessUpdate,\n encodeAwarenessUpdate,\n} from \"y-protocols/awareness\";\nimport { IFRAME_ORIGIN, BASELINE_ORIGIN } from \"./origin.js\";\n\nexport interface IframeBridgeServerOptions {\n undoManager?: Y.UndoManager;\n}\n\nexport interface IframeBridgeServer {\n connected: boolean;\n onConnect: (fn: () => void) => () => void;\n onDisconnect: (fn: () => void) => () => void;\n on: (event: \"connect\" | \"disconnect\", fn: () => void) => () => void;\n destroy: () => void;\n}\n\nexport function createIframeBridgeServer(\n iframe: HTMLIFrameElement,\n ydoc: Y.Doc,\n awareness: Awareness,\n options?: IframeBridgeServerOptions,\n): IframeBridgeServer {\n const { undoManager } = options ?? {};\n let connected = false;\n let applyingIframeUpdate = false;\n const connectListeners = new Set<() => void>();\n const disconnectListeners = new Set<() => void>();\n\n function setConnected(value: boolean) {\n if (connected === value) return;\n connected = value;\n if (value) {\n connectListeners.forEach((fn) => fn());\n } else {\n disconnectListeners.forEach((fn) => fn());\n }\n }\n\n function postToIframe(type: string, payload?: Uint8Array) {\n const cw = iframe.contentWindow;\n if (cw) {\n cw.postMessage(\n { type, payload: payload ? Array.from(payload) : [] },\n \"*\",\n );\n }\n }\n\n function postUndoStateToIframe() {\n if (!undoManager) return;\n const undoStack = (undoManager as any).undoStack;\n const redoStack = (undoManager as any).redoStack;\n const cw = iframe.contentWindow;\n if (cw) {\n const state = {\n type: \"undo-state\",\n canUndo: undoManager.canUndo(),\n canRedo: undoManager.canRedo(),\n undoStackSize: undoStack?.length ?? 0,\n redoStackSize: redoStack?.length ?? 0,\n };\n cw.postMessage(state, \"*\");\n }\n }\n\n const onYdocUpdate = (update: Uint8Array, origin: unknown) => {\n if (origin === IFRAME_ORIGIN) return;\n postToIframe(\"ydoc-update\", update);\n };\n\n const onAwarenessUpdate = ({\n added,\n updated,\n removed,\n }: {\n added: number[];\n updated: number[];\n removed: number[];\n }) => {\n if (applyingIframeUpdate) return;\n const changes = [...added, ...updated, ...removed];\n if (changes.length === 0) return;\n\n // 把所有变化的 clientID 都发送给 iframe(包括其他 Webrtc peers 的光标更新)\n // 但要注意:server 自身的 clientID 需要被 iframe 识别为 serverClientId\n const update = encodeAwarenessUpdate(awareness, changes);\n postToIframe(\"awareness-update\", update);\n };\n\n const onMessage = (event: MessageEvent) => {\n if (event.source !== iframe.contentWindow) return;\n\n const { type: msgType, payload } = event.data;\n\n if (msgType === \"init\") {\n console.log(\n `[iframe-bridge server] received init — connected=${connected}`,\n );\n if (!connected) {\n setConnected(true);\n }\n const docState = Y.encodeStateAsUpdate(ydoc);\n console.log(\n `[iframe-bridge server] sending ydoc-sync — docState bytes=${docState.length}`,\n );\n const awarenessState = encodeAwarenessUpdate(\n awareness,\n Array.from(awareness.getStates().keys()),\n );\n postToIframe(\"ydoc-sync\", new Uint8Array(Array.from(docState)));\n // 在单独的 postMessage 中发送 serverClientId,方便 iframe 接收\n const cw = iframe.contentWindow;\n if (cw) {\n cw.postMessage(\n {\n type: \"awareness-sync\",\n payload: Array.from(awarenessState),\n serverClientId: awareness.clientID,\n },\n \"*\",\n );\n }\n // 同步初始 undo 状态\n postUndoStateToIframe();\n } else if (msgType === \"ping\") {\n const cw = iframe.contentWindow;\n if (cw) {\n cw.postMessage(\n { type: \"pong\", serverClientId: awareness.clientID },\n \"*\",\n );\n }\n } else if (msgType === \"ydoc-update\") {\n const update = new Uint8Array(payload);\n const isBaseline = event.data.isBaseline;\n // 基线数据使用 BASELINE_ORIGIN(不进入 undo 栈),编辑数据使用 IFRAME_ORIGIN\n const applyOrigin = isBaseline ? BASELINE_ORIGIN : IFRAME_ORIGIN;\n Y.applyUpdate(ydoc, update, applyOrigin);\n // 源 iframe 已经持有此 update,无需回传\n } else if (msgType === \"awareness-update\") {\n // 应用 iframe 的 awareness 更新时设置标志,防止触发 onAwarenessUpdate 回传\n applyingIframeUpdate = true;\n applyAwarenessUpdate(awareness, new Uint8Array(payload), IFRAME_ORIGIN);\n applyingIframeUpdate = false;\n } else if (msgType === \"undo\" && undoManager) {\n undoManager.undo();\n postUndoStateToIframe();\n } else if (msgType === \"redo\" && undoManager) {\n undoManager.redo();\n postUndoStateToIframe();\n }\n };\n\n const onUndoPopped = () => {\n postUndoStateToIframe();\n };\n\n const onStackCleared = () => {\n postUndoStateToIframe();\n };\n\n const onStackItemAdded = () => {\n postUndoStateToIframe();\n };\n\n ydoc.on(\"update\", onYdocUpdate);\n awareness.on(\"update\", onAwarenessUpdate);\n window.addEventListener(\"message\", onMessage);\n if (undoManager) {\n undoManager.on(\"stack-item-popped\", onUndoPopped);\n undoManager.on(\"stack-cleared\", onStackCleared);\n undoManager.on(\"stack-item-added\", onStackItemAdded);\n }\n\n return {\n get connected() {\n return connected;\n },\n onConnect(fn: () => void) {\n connectListeners.add(fn);\n return () => connectListeners.delete(fn);\n },\n onDisconnect(fn: () => void) {\n disconnectListeners.add(fn);\n return () => disconnectListeners.delete(fn);\n },\n on(event: \"connect\" | \"disconnect\", fn: () => void) {\n if (event === \"connect\") {\n connectListeners.add(fn);\n return () => connectListeners.delete(fn);\n } else {\n disconnectListeners.add(fn);\n return () => disconnectListeners.delete(fn);\n }\n },\n destroy: () => {\n setConnected(false);\n postToIframe(\"disconnect\");\n ydoc.off(\"update\", onYdocUpdate);\n awareness.off(\"update\", onAwarenessUpdate);\n window.removeEventListener(\"message\", onMessage);\n if (undoManager) {\n undoManager.off(\"stack-item-popped\", onUndoPopped);\n undoManager.off(\"stack-cleared\", onStackCleared);\n undoManager.off(\"stack-item-added\", onStackItemAdded);\n }\n connectListeners.clear();\n disconnectListeners.clear();\n },\n };\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index-CcOHH2TY.cjs","sources":["../src/helper/xml.ts","../src/models/mxCell.ts","../src/models/mxGraphModel.ts","../src/models/diagram.ts","../src/models/mxfile.ts","../src/transformer/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, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\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 * 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 xml2ydoc(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 ydoc2xml(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"],"names":["key","parse","xml2js","serializer","js2xml","Y","serialize","mxCellKey","parseMxCell","serializeMxCell","parseMxGraphModel","mxGraphModelKey","serializeMxGraphModel","diagramKey","_a","parseDiagram","serializeDiagram","parseMxFile","mxfileKey","serializerMxFile","serializerMxGraphModel"],"mappings":"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"}
1
+ {"version":3,"file":"index-CcOHH2TY.cjs","sources":["../src/helper/xml.ts","../src/models/mxCell.ts","../src/models/mxGraphModel.ts","../src/models/diagram.ts","../src/models/mxfile.ts","../src/transform/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, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\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 * 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 xml2ydoc(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 ydoc2xml(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"],"names":["key","parse","xml2js","serializer","js2xml","Y","serialize","mxCellKey","parseMxCell","serializeMxCell","parseMxGraphModel","mxGraphModelKey","serializeMxGraphModel","diagramKey","_a","parseDiagram","serializeDiagram","parseMxFile","mxfileKey","serializerMxFile","serializerMxGraphModel"],"mappings":";;;;;;;;;;;;;;;;;;;;AAEA,SAAS,YAAY,MAAqB;AACxC,MAAI,QAAQ,KAAM;AAElB,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,eAAW,QAAQ,MAAM;AACvB,kBAAY,IAAI;AAAA,IAClB;AACA;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,SAAU;AAE9B,QAAM,MAAM;AACZ,QAAM,OAAO,OAAO,KAAK,GAAG;AAC5B,aAAWA,QAAO,MAAM;AACtB,QAAIA,SAAQ,cAAe;AAE3B,QAAI,QAAQ,IAAIA,IAAG;AACnB,UAAM,WAAWA,KAAI,YAAA;AAErB,SACG,aAAa,aAAa,aAAa,aACxC,UAAU,UACV,CAAC,MAAM,QAAQ,KAAK,GACpB;AACA,UAAIA,IAAG,IAAI,CAAC,KAAK;AACjB,cAAQ,IAAIA,IAAG;AAAA,IACjB;AAEA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,iBAAW,KAAK,MAAO,aAAY,CAAC;AAAA,IACtC,WAAW,SAAS,OAAO,UAAU,UAAU;AAC7C,kBAAY,KAAK;AAAA,IACnB;AAAA,EACF;AACF;AAEO,SAASC,QAAM,KAAa;AACjC,QAAM,SAASC,MAAAA,OAAO,KAAK,EAAE,SAAS,MAAM;AAC5C,cAAY,MAAM;AAClB,SAAO;AACT;AAEO,SAASC,aAAW,KAAqB,SAAS,GAAG;AAC1D,SAAOC,MAAAA,OAAO,KAAK;AAAA,IACjB,SAAS;AAAA,IACT;AAAA,EAAA,CACD;AACH;;;;;;;;;;;;;;;;;AC9CO,MAAMJ,QAAM;AAEnB,MAAM,gBAAgB;AACtB,MAAM,yBAAyB;AAMxB,SAASC,QAAM,QAAmC;AAbzD,MAAA;AAcE,QAAM,aAAa,IAAII,aAAE,WAAW,QAAQ;AAE5C,aAAW,aAAa,OAAO,KAAK,OAAO,eAAe,CAAA,CAAE,GAAG;AAC7D,eAAW;AAAA,MACT;AAAA,MACA,KAAG,KAAA,OAAO,gBAAP,OAAA,SAAA,GAAqB,eAAc,EAAE;AAAA,IAAA;AAAA,EAE5C;AAEA,MAAI,OAAO,aAAa,GAAG;AACzB,UAAM,WAAW,OAAO,aAAa;AACrC,UAAM,iBAAiBD,MAAAA,OAAO,UAAU;AAAA,MACtC,SAAS;AAAA,IAAA,CACV;AACD,eAAW,aAAa,wBAAwB,cAAc;AAC9D,WAAO,OAAO,aAAa;AAAA,EAC7B;AAEA,SAAO;AACT;AAEO,SAASE,YAAU,YAA0B;AAnCpD,MAAA;AAoCE,QAAM,gBAAgB,eAAA,CAAA,GACjB,WAAW,cAAA,CAAc;AAI9B,MAAI,aAAoC;AACxC,MAAI;AAEJ,MAAI,0BAA0B,eAAe;AAC3C,uBAAmB,cAAc,sBAAsB;AACvD,WAAO,cAAc,sBAAsB;AAAA,EAC7C;AAGA,QAAM,aAAqC,CAAA;AAC3C,aAAW,CAACN,MAAK,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACxD,QAAI,OAAO,UAAU,UAAU;AAC7B,iBAAWA,IAAG,IAAI,MACf,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,QAAQ;AAAA,IAC3B,WAAW,SAAS,MAAM;AACxB,iBAAWA,IAAG,IAAI,OAAO,KAAK;AAAA,IAChC;AAAA,EACF;AAGA,MAAI,kBAAkB;AACpB,QAAI;AACF,YAAM,SAASE,MAAAA,OAAO,kBAAkB,EAAE,SAAS,MAAM;AACzD,oBAAa,KAAA,OAAO,aAAa,MAApB,OAAA,KAAyB;AACtC,UAAI,cAAc,WAAW,aAAa;AACxC,mBAAW,YAAY,IAAI,IAAI;AAAA,MACjC;AAAA,IACF,SAAS,GAAG;AACV,cAAQ,KAAK,2CAA2C,CAAC;AAAA,IAC3D;AAAA,EACF;AAEA,QAAM,MAA+B;AAAA,IACnC,aAAa;AAAA,EAAA;AAGf,MAAI,YAAY;AACd,QAAI,aAAa,IAAI;AAAA,EACvB;AAEA,SAAO;AACT;AC5EO,MAAMF,QAAM;AACZ,MAAM,iBAAiBO,QAAY;AAUnC,SAASN,QAAM,QAAsB,KAAa;AACvD,QAAM,WAAW,OAAO,KAAKM,KAAS,KAAK,CAAA,GAAI,IAAI,CAAC,SAAsB;AAtB5E,QAAA;AAuBI,WAAO;AAAA,MACL,OAAOC,QAAY,IAAI;AAAA,MACvB,MAAK,KAAA,KAAK,gBAAL,OAAA,SAAA,GAAkB,OAAM;AAAA,IAAA;AAAA,EAEjC,CAAC;AAED,QAAM,kBAAiB,OAAA,OAAA,SAAA,IAAK,OAAOR,KAAA,MAAQ,IAAIK,aAAE,IAAA;AAEjD,QAAM,QAAQ,IAAIA,aAAE,IAAA;AACpB,QAAM,aAAa,IAAIA,aAAE,MAAA;AAEzB,UAAQ,QAAQ,CAAC,SAAS;AACxB,UAAM,IAAI,KAAK,IAAI,KAAK,KAAK;AAAA,EAC/B,CAAC;AAED,aAAW,KAAK,QAAQ,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC;AAE9C,iBAAe,IAAIE,OAAW,KAAK;AACnC,iBAAe,IAAI,gBAAgB,UAAU;AAE7C,SAAO;AACT;AAEO,SAASD,YAAU,KAAoB;AAC5C,QAAM,QAAQ,IAAI,IAAIC,KAAS;AAC/B,QAAM,aAAa,IAAI,IAAI,cAAc;AACzC,SAAO;AAAA,IACL,aAAa,CAAA;AAAA,IACb,MAAM;AAAA,MACJ,CAACA,KAAS,GAAG,WACV,UACA,IAAI,CAAC,OAAOE,YAAgB,MAAM,IAAI,EAAE,CAAiB,CAAC;AAAA,IAAA;AAAA,EAC/D;AAEJ;AC/CO,MAAMT,QAAM;AAQZ,SAASC,QAAM,QAA2B;AAlBjD,MAAA,IAAA;AAmBE,QAAM,kBAAkB,IAAII,aAAE,IAAA;AAC9B,kBAAgB,IAAI,QAAQ,KAAG,KAAA,OAAO,gBAAP,OAAA,SAAA,GAAoB,SAAQ,EAAE,EAAE;AAC/D,kBAAgB,IAAI,MAAM,KAAG,KAAA,OAAO,gBAAP,OAAA,SAAA,GAAoB,OAAM,EAAE,EAAE;AAE3D,QAAM,eAAeK,QAAkB,OAAOC,KAAe,CAAC;AAE9D,kBAAgB,IAAIA,OAAiB,YAAY;AACjD,SAAO;AACT;AAEO,SAAS,UAAU,UAAoB;AAC5C,QAAM,eAAe,SAAS,IAAIA,KAAe;AAIjD,SAAO;AAAA,IACL,aAAa;AAAA,MACX,MAAM,SAAS,IAAI,MAAM;AAAA,MACzB,IAAI,SAAS,IAAI,IAAI;AAAA,IAAA;AAAA,IAEvB,CAACA,KAAe,GAAG,eACfC,YAAsB,YAAY,IAClC;AAAA,EAAA;AAER;AClCO,MAAM,MAAM;AACZ,MAAM,kBAAkBC,QAAa;AAQrC,SAAS,MAAM,QAAgB,KAAY;AAlBlD,MAAA;AAmBE,QAAM,SAAS,IAAI,OAAO,GAAG;AAC7B,SAAO,IAAI,YAAU,KAAA,OAAO,gBAAP,OAAA,SAAA,GAAoB,UAAS,OAAO,EAAE;AAE3D,QAAM,cAAc,OAAO,QAAQ,IAAI,CAAC,YAAS;AAtBnD,QAAAC;AAsBuD,WAAA;AAAA,MACnD,OAAOC,QAAa,OAAO;AAAA,MAC3B,MAAKD,MAAA,QAAQ,gBAAR,OAAA,SAAAA,IAAqB,OAAM;AAAA,IAAA;AAAA,EAClC,CAAE;AACF,QAAM,aAAa,IAAIT,aAAE,IAAA;AACzB,QAAM,eAAe,IAAIA,aAAE,MAAA;AAC3B,cAAY,QAAQ,CAAC,YAAY;AAC/B,eAAW,IAAI,QAAQ,IAAI,QAAQ,KAAK;AAAA,EAC1C,CAAC;AACD,eAAa,KAAK,YAAY,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC;AAE1D,SAAO,IAAIQ,OAAY,UAAU;AACjC,SAAO,IAAI,iBAAiB,YAAY;AACxC,SAAO;AACT;AAEO,SAAS,WAAW,SAAkC;AAC3D,QAAM,WAAW,QAAQ,IAAIA,KAAU;AACvC,QAAM,eAAe,QAAQ;AAAA,IAC3B;AAAA,EAAA;AAGF,QAAM,WAAW,eAAe,aAAa,QAAA,IAAY,CAAA;AAEzD,QAAM,MAAM,SAAS,SAAS,IAAI,WAAY,WAAW,MAAM,KAAK,SAAS,KAAA,CAAM,IAAI,CAAA;AAEvF,QAAM,MAA+B;AAAA,IACnC,aAAa;AAAA,MACX,OAAQ,QAAQ,IAAI,OAAO,KAAgB;AAAA,IAAA;AAAA,IAE7C,CAACA,KAAU,GAAG,IACX,IAAI,CAAC,OAAO,SAAS,IAAI,EAAE,CAAwB,EACnD,OAAO,CAAC,MAAqB,CAAC,CAAC,CAAC,EAChC,IAAI,CAAC,mBAAmBG,UAAiB,cAAc,CAAC;AAAA,EAAA;AAG7D,SAAO;AACT;AC5CO,SAAS,SAAS,KAAa,KAAmB;AACvD,QAAM,SAASf,QAAM,GAAG;AAExB,QAAM,SAAU,OAAmC;AACnD,QAAM,eAAgB,OAAmC;AACzD,MAAI,QAAQ;AACV,QAAI,SAAS,MAAM;AACjBgB,YAAY,QAA6C,GAAG;AAAA,IAC9D,CAAC;AAAA,EACH,WAAW,cAAc;AACvB,QAAI,SAAS,MAAM;AACjBP,cAAkB,cAA+D,GAAG;AAAA,IACtF,CAAC;AAAA,EACH,OAAO;AACL,UAAM,IAAI,MAAM,UAAU;AAAA,EAC5B;AAEA,SAAO;AACT;AAEO,SAAS,SAAS,KAAY,SAAS,GAAW;AACvD,MAAI,IAAI,MAAM,IAAIQ,GAAS,GAAG;AAC5B,WAAOf;AAAAA,MACL;AAAA,QACE,CAACe,GAAS,GAAGC;AAAAA,UACX,IAAI,MAAM,IAAID,GAAS;AAAA,QAAA;AAAA,MACzB;AAAA,MAEF;AAAA,IAAA;AAAA,EAEJ,WAAW,IAAI,MAAM,IAAIP,KAAe,GAAG;AACzC,WAAOR;AAAAA,MACL;AAAA,QACE,CAACQ,KAAe,GAAGS;AAAAA,UACjB,IAAI,MAAM,IAAIT,KAAe;AAAA,QAAA;AAAA,MAC/B;AAAA,MAEF;AAAA,IAAA;AAAA,EAEJ;AAEA,SAAO;AACT;;;;;;;;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"index-DBU79c0g.js","sources":["../src/helper/xml.ts","../src/models/mxCell.ts","../src/models/mxGraphModel.ts","../src/models/diagram.ts","../src/models/mxfile.ts","../src/transformer/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, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\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 * 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 xml2ydoc(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 ydoc2xml(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"],"names":["key","parse","serializer","serialize","mxCellKey","parseMxCell","serializeMxCell","parseMxGraphModel","mxGraphModelKey","serializeMxGraphModel","diagramKey","_a","parseDiagram","serializeDiagram","parseMxFile","mxfileKey","serializerMxFile","serializerMxGraphModel"],"mappings":"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"}
1
+ {"version":3,"file":"index-DBU79c0g.js","sources":["../src/helper/xml.ts","../src/models/mxCell.ts","../src/models/mxGraphModel.ts","../src/models/diagram.ts","../src/models/mxfile.ts","../src/transform/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, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;')\n .replace(/'/g, '&apos;');\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 * 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 xml2ydoc(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 ydoc2xml(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"],"names":["key","parse","serializer","serialize","mxCellKey","parseMxCell","serializeMxCell","parseMxGraphModel","mxGraphModelKey","serializeMxGraphModel","diagramKey","_a","parseDiagram","serializeDiagram","parseMxFile","mxfileKey","serializerMxFile","serializerMxGraphModel"],"mappings":"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"}
package/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { Binding } from "./binding";
2
2
  export type { BindDrawioFileOptions, InitialContentStrategy } from "./binding";
3
- export { xml2ydoc, ydoc2xml } from "./transformer";
3
+ export { xml2ydoc, ydoc2xml } from "./transform";
4
4
  export { LOCAL_ORIGIN } from "./helper/origin";
5
5
  export { DEFAULT_USER_NAME_KEY, DEFAULT_USER_COLOR_KEY, } from "./binding/collaborator";
6
6
  //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "y-mxgraph",
3
- "version": "0.5.8",
3
+ "version": "0.6.1",
4
4
  "description": "Yjs binding for draw.io (mxGraph) documents",
5
5
  "keywords": [
6
6
  "yjs",
@@ -34,10 +34,10 @@
34
34
  "require": "./iframe-bridge/provider.cjs",
35
35
  "types": "./iframe-bridge/provider.d.ts"
36
36
  },
37
- "./transformer": {
38
- "import": "./transformer.js",
39
- "require": "./transformer.cjs",
40
- "types": "./transformer.d.ts"
37
+ "./transform": {
38
+ "import": "./transform.js",
39
+ "require": "./transform.cjs",
40
+ "types": "./transform.d.ts"
41
41
  }
42
42
  },
43
43
  "dependencies": {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transform/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAezB,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAkBvD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,SAAI,GAAG,MAAM,CAsBvD"}
package/transform.cjs ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const transform = require("./index-CcOHH2TY.cjs");
4
+ exports.xml2ydoc = transform.xml2ydoc;
5
+ exports.ydoc2xml = transform.ydoc2xml;
6
+ //# sourceMappingURL=transform.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
@@ -3,4 +3,4 @@ export {
3
3
  x as xml2ydoc,
4
4
  y as ydoc2xml
5
5
  };
6
- //# sourceMappingURL=transformer.js.map
6
+ //# sourceMappingURL=transform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
package/y-mxgraph.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const transformer = require("./index-CcOHH2TY.cjs");
3
+ const transform = require("./index-CcOHH2TY.cjs");
4
4
  const Y = require("yjs");
5
5
  const colord = require("colord");
6
6
  function _interopNamespaceDefault(e) {
@@ -74,11 +74,11 @@ function ensureUniqueOrder(orderArr) {
74
74
  }
75
75
  function applyFilePatch(doc, patch, options) {
76
76
  doc.transact(() => {
77
- const mxfile = doc.getMap(transformer.key);
77
+ const mxfile = doc.getMap(transform.key);
78
78
  if (patch[DIFF_REMOVE]) {
79
- const diagramsMap = mxfile.get(transformer.key$1);
79
+ const diagramsMap = mxfile.get(transform.key$1);
80
80
  const orderArr = mxfile.get(
81
- transformer.diagramOrderKey
81
+ transform.diagramOrderKey
82
82
  );
83
83
  ensureUniqueOrder(orderArr);
84
84
  const orderList = orderArr.toArray();
@@ -90,9 +90,9 @@ function applyFilePatch(doc, patch, options) {
90
90
  }
91
91
  }
92
92
  if (patch[DIFF_INSERT]) {
93
- const diagramsMap = mxfile.get(transformer.key$1);
93
+ const diagramsMap = mxfile.get(transform.key$1);
94
94
  const orderArr = mxfile.get(
95
- transformer.diagramOrderKey
95
+ transform.diagramOrderKey
96
96
  );
97
97
  ensureUniqueOrder(orderArr);
98
98
  const currentOrder = orderArr.toArray();
@@ -105,9 +105,9 @@ function applyFilePatch(doc, patch, options) {
105
105
  const existingIndex = /* @__PURE__ */ new Map();
106
106
  existingIds.forEach((id, idx) => existingIndex.set(id, idx));
107
107
  const inserts = patch[DIFF_INSERT].map((item, order) => {
108
- const object = transformer.parse(item.data);
108
+ const object = transform.parse(item.data);
109
109
  const diagramObj = Array.isArray(object == null ? void 0 : object.diagram) ? object.diagram[0] : object == null ? void 0 : object.diagram;
110
- const diagramElement = transformer.parse$1(
110
+ const diagramElement = transform.parse$1(
111
111
  diagramObj
112
112
  );
113
113
  return {
@@ -161,7 +161,7 @@ function applyFilePatch(doc, patch, options) {
161
161
  if (patch[DIFF_UPDATE]) {
162
162
  Object.keys(patch[DIFF_UPDATE]).forEach((id) => {
163
163
  const diagramsMap = mxfile.get(
164
- transformer.key$1
164
+ transform.key$1
165
165
  );
166
166
  const diagram = diagramsMap.get(id);
167
167
  if (diagram) {
@@ -173,10 +173,10 @@ function applyFilePatch(doc, patch, options) {
173
173
  );
174
174
  }
175
175
  if (update.cells) {
176
- const yMxGraphModel = diagram.get(transformer.key$2);
176
+ const yMxGraphModel = diagram.get(transform.key$2);
177
177
  if (!yMxGraphModel) return;
178
- const cellsMap = yMxGraphModel.get(transformer.key$3);
179
- const orderArr = yMxGraphModel.get(transformer.mxCellOrderKey);
178
+ const cellsMap = yMxGraphModel.get(transform.key$3);
179
+ const orderArr = yMxGraphModel.get(transform.mxCellOrderKey);
180
180
  if (!cellsMap || !orderArr) return;
181
181
  ensureUniqueOrder(orderArr);
182
182
  if (update.cells[DIFF_REMOVE] && update.cells[DIFF_REMOVE].length) {
@@ -296,7 +296,7 @@ function applyFilePatch(doc, patch, options) {
296
296
  if ("previous" in update) {
297
297
  const previous = update.previous || null;
298
298
  const orderArr = mxfile.get(
299
- transformer.diagramOrderKey
299
+ transform.diagramOrderKey
300
300
  );
301
301
  ensureUniqueOrder(orderArr);
302
302
  insertAfterUnique(orderArr, id, previous, false);
@@ -308,9 +308,9 @@ function applyFilePatch(doc, patch, options) {
308
308
  }
309
309
  function initDocSnapshot(doc, resetSnapshot = false) {
310
310
  try {
311
- const mxfile = doc.getMap(transformer.key);
312
- const diagramsMap = mxfile.get(transformer.key$1);
313
- const orderArr = mxfile.get(transformer.diagramOrderKey);
311
+ const mxfile = doc.getMap(transform.key);
312
+ const diagramsMap = mxfile.get(transform.key$1);
313
+ const orderArr = mxfile.get(transform.diagramOrderKey);
314
314
  const orderIds = orderArr ? orderArr.toArray() : [];
315
315
  const allDiagramIds = orderIds.length > 0 ? orderIds : diagramsMap ? Array.from(diagramsMap.keys()) : [];
316
316
  const diagramOrder = resetSnapshot ? [] : allDiagramIds.slice();
@@ -323,12 +323,12 @@ function initDocSnapshot(doc, resetSnapshot = false) {
323
323
  for (const d of diagrams) {
324
324
  const did = d.get("id") || "";
325
325
  if (!did) continue;
326
- const gm = d.get(transformer.key$2);
326
+ const gm = d.get(transform.key$2);
327
327
  if (gm) {
328
- const order = gm.get(transformer.mxCellOrderKey);
328
+ const order = gm.get(transform.mxCellOrderKey);
329
329
  const ids = order ? order.toArray().slice() : [];
330
330
  snap.cellsOrder.set(did, ids);
331
- const cellsMap = gm.get(transformer.key$3);
331
+ const cellsMap = gm.get(transform.key$3);
332
332
  const attrMap = /* @__PURE__ */ new Map();
333
333
  if (cellsMap) {
334
334
  for (const cid of ids) {
@@ -358,9 +358,9 @@ function generatePatch(events, explicitDoc) {
358
358
  const doc = (_b = (_a = events[0]) == null ? void 0 : _a.transaction) == null ? void 0 : _b.doc;
359
359
  if (!doc) return patch;
360
360
  if (!events || events.length === 0) return patch;
361
- const mxfile = doc.getMap(transformer.key);
362
- const diagramsMap = mxfile.get(transformer.key$1);
363
- const orderArr = mxfile.get(transformer.diagramOrderKey);
361
+ const mxfile = doc.getMap(transform.key);
362
+ const diagramsMap = mxfile.get(transform.key$1);
363
+ const orderArr = mxfile.get(transform.diagramOrderKey);
364
364
  let snap = docSnapshots.get(doc);
365
365
  if (!snap) {
366
366
  snap = {
@@ -391,10 +391,10 @@ function generatePatch(events, explicitDoc) {
391
391
  for (const d of diagramsList) {
392
392
  const did = d.get("id") || "";
393
393
  const attrs = /* @__PURE__ */ new Map();
394
- const gm = d.get(transformer.key$2);
394
+ const gm = d.get(transform.key$2);
395
395
  if (gm) {
396
- const cellsMap = gm.get(transformer.key$3);
397
- const orderArr2 = gm.get(transformer.mxCellOrderKey);
396
+ const cellsMap = gm.get(transform.key$3);
397
+ const orderArr2 = gm.get(transform.mxCellOrderKey);
398
398
  if (cellsMap && orderArr2) {
399
399
  const ids = orderArr2.toArray();
400
400
  currCellsOrder.set(did, ids);
@@ -431,7 +431,7 @@ function generatePatch(events, explicitDoc) {
431
431
  const previous = index <= 0 ? "" : currDiagramOrder[index - 1];
432
432
  const yDiagram = diagramsMap.get(id);
433
433
  if (!yDiagram) continue;
434
- const data = transformer.serializer({ diagram: transformer.serialize(yDiagram) });
434
+ const data = transform.serializer({ diagram: transform.serialize(yDiagram) });
435
435
  patch[DIFF_INSERT].push({ id, previous, data });
436
436
  insertedDiagramIdGlobal.add(id);
437
437
  }
@@ -1236,7 +1236,7 @@ const defaultApplyFileData = (file, xml) => {
1236
1236
  function mergeFileIntoDoc(doc, fileXml, strategy) {
1237
1237
  let parsed;
1238
1238
  try {
1239
- parsed = transformer.parse(fileXml);
1239
+ parsed = transform.parse(fileXml);
1240
1240
  } catch (err) {
1241
1241
  console.warn(
1242
1242
  "[y-mxgraph] 合并失败,file XML 解析异常,回退到 replace:",
@@ -1251,9 +1251,9 @@ function mergeFileIntoDoc(doc, fileXml, strategy) {
1251
1251
  );
1252
1252
  return false;
1253
1253
  }
1254
- const mxfileMap = doc.getMap(transformer.key);
1255
- const diagramMap = mxfileMap.get(transformer.key$1);
1256
- const diagramOrder = mxfileMap.get(transformer.diagramOrderKey);
1254
+ const mxfileMap = doc.getMap(transform.key);
1255
+ const diagramMap = mxfileMap.get(transform.key$1);
1256
+ const diagramOrder = mxfileMap.get(transform.diagramOrderKey);
1257
1257
  if (!diagramMap || !diagramOrder) {
1258
1258
  console.warn("[y-mxgraph] 合并失败,doc 结构不完整,回退到 replace");
1259
1259
  return false;
@@ -1267,7 +1267,7 @@ function mergeFileIntoDoc(doc, fileXml, strategy) {
1267
1267
  if (docHas && strategy === "merge-remote") {
1268
1268
  continue;
1269
1269
  }
1270
- const yDiagram = transformer.parse$1(
1270
+ const yDiagram = transform.parse$1(
1271
1271
  diagram
1272
1272
  );
1273
1273
  diagramMap.set(id, yDiagram);
@@ -1279,13 +1279,13 @@ function mergeFileIntoDoc(doc, fileXml, strategy) {
1279
1279
  return true;
1280
1280
  }
1281
1281
  function reconcileInitialContent(doc, file, strategy, applyFileData) {
1282
- const mxfileMap = doc.getMap(transformer.key);
1282
+ const mxfileMap = doc.getMap(transform.key);
1283
1283
  const docHasData = mxfileMap.size > 0;
1284
1284
  const fileHasAnyData = !!file.data;
1285
1285
  const fileHasDiagrams = fileHasAnyData && file.data.includes("<diagram");
1286
1286
  if (strategy === "replace") {
1287
1287
  if (docHasData) {
1288
- const xml2 = transformer.ydoc2xml(doc);
1288
+ const xml2 = transform.ydoc2xml(doc);
1289
1289
  if (xml2 && xml2.includes("<diagram")) {
1290
1290
  applyFileData(file, xml2);
1291
1291
  } else if (!fileHasAnyData) {
@@ -1305,7 +1305,7 @@ function reconcileInitialContent(doc, file, strategy, applyFileData) {
1305
1305
  if (!docHasData && fileHasDiagrams) {
1306
1306
  try {
1307
1307
  doc.transact(() => {
1308
- transformer.xml2ydoc(file.data, doc);
1308
+ transform.xml2ydoc(file.data, doc);
1309
1309
  });
1310
1310
  return true;
1311
1311
  } catch (err) {
@@ -1318,7 +1318,7 @@ function reconcileInitialContent(doc, file, strategy, applyFileData) {
1318
1318
  }
1319
1319
  }
1320
1320
  if (docHasData && !fileHasDiagrams) {
1321
- const xml2 = transformer.ydoc2xml(doc);
1321
+ const xml2 = transform.ydoc2xml(doc);
1322
1322
  if (xml2 && xml2.includes("<diagram")) {
1323
1323
  applyFileData(file, xml2);
1324
1324
  } else if (!fileHasAnyData) {
@@ -1328,11 +1328,11 @@ function reconcileInitialContent(doc, file, strategy, applyFileData) {
1328
1328
  }
1329
1329
  const ok = mergeFileIntoDoc(doc, file.data, strategy);
1330
1330
  if (!ok) {
1331
- const xml2 = transformer.ydoc2xml(doc);
1331
+ const xml2 = transform.ydoc2xml(doc);
1332
1332
  if (xml2 && xml2.includes("<diagram")) applyFileData(file, xml2);
1333
1333
  return mxfileMap.size > 0;
1334
1334
  }
1335
- const xml = transformer.ydoc2xml(doc);
1335
+ const xml = transform.ydoc2xml(doc);
1336
1336
  if (xml && xml.includes("<diagram")) applyFileData(file, xml);
1337
1337
  return true;
1338
1338
  }
@@ -1386,7 +1386,7 @@ class Binding {
1386
1386
  if (patchKeys.length === 0) return;
1387
1387
  if (!this.docInitialized) {
1388
1388
  doc.transact(() => {
1389
- transformer.xml2ydoc(file.data, doc);
1389
+ transform.xml2ydoc(file.data, doc);
1390
1390
  initDocSnapshot(doc, false);
1391
1391
  });
1392
1392
  this.docInitialized = true;
@@ -1402,10 +1402,10 @@ class Binding {
1402
1402
  return;
1403
1403
  }
1404
1404
  if (this.shouldReplaceWhenDocHasData && !transaction.local) {
1405
- const mxfileMap = doc.getMap(transformer.key);
1406
- const diagramMap = mxfileMap.get(transformer.key$1);
1405
+ const mxfileMap = doc.getMap(transform.key);
1406
+ const diagramMap = mxfileMap.get(transform.key$1);
1407
1407
  if (diagramMap && diagramMap.size > 0) {
1408
- const xml = transformer.ydoc2xml(doc);
1408
+ const xml = transform.ydoc2xml(doc);
1409
1409
  if (xml && xml.includes("<diagram")) {
1410
1410
  this.suppressLocalApply = true;
1411
1411
  try {
@@ -1435,7 +1435,7 @@ class Binding {
1435
1435
  this.suppressLocalApply = false;
1436
1436
  }
1437
1437
  };
1438
- doc.getMap(transformer.key).observeDeep(this.docObserver);
1438
+ doc.getMap(transform.key).observeDeep(this.docObserver);
1439
1439
  if (awareness) {
1440
1440
  this.cleanupCollaborator = bindCollaborator(file, {
1441
1441
  awareness,
@@ -1470,7 +1470,7 @@ class Binding {
1470
1470
  destroy(deep = false) {
1471
1471
  var _a, _b;
1472
1472
  this.mxGraphModel.removeListener("change", this.mxListener);
1473
- this.doc.getMap(transformer.key).unobserveDeep(this.docObserver);
1473
+ this.doc.getMap(transform.key).unobserveDeep(this.docObserver);
1474
1474
  if (deep) {
1475
1475
  (_a = this.cleanupCollaborator) == null ? void 0 : _a.call(this);
1476
1476
  (_b = this.cleanupUndoManager) == null ? void 0 : _b.call(this);
@@ -1511,8 +1511,8 @@ class Binding {
1511
1511
  return new Binding(file, options);
1512
1512
  }
1513
1513
  }
1514
- exports.xml2ydoc = transformer.xml2ydoc;
1515
- exports.ydoc2xml = transformer.ydoc2xml;
1514
+ exports.xml2ydoc = transform.xml2ydoc;
1515
+ exports.ydoc2xml = transform.ydoc2xml;
1516
1516
  exports.Binding = Binding;
1517
1517
  exports.DEFAULT_USER_COLOR_KEY = DEFAULT_USER_COLOR_KEY;
1518
1518
  exports.DEFAULT_USER_NAME_KEY = DEFAULT_USER_NAME_KEY;