y-mxgraph 0.1.3 → 0.1.5

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/README.md CHANGED
@@ -29,8 +29,8 @@ import { Binding, LOCAL_ORIGIN } from 'y-mxgraph';
29
29
  const doc = new Y.Doc();
30
30
 
31
31
  App.main((app) => {
32
- // 确保多端初始文件一致;draw.io 默认创建时 diagram id 是随机的,
33
- // 若各客户端起点不同会导致协同异常。可用 generateFileTemplate 生成统一模板。
32
+ // Ensure consistent initial files across clients. draw.io generates random diagram ids by default,
33
+ // which can cause sync issues if clients start from different states. Use generateFileTemplate to create a unified template.
34
34
  if (!app.currentFile.data) {
35
35
  app.currentFile.data = Binding.generateFileTemplate('diagram-0');
36
36
  }
@@ -62,21 +62,26 @@ pnpm --filter y-mxgraph build
62
62
 
63
63
  # Test
64
64
  pnpm --filter y-mxgraph test
65
+ ```
65
66
 
66
- # Demo
67
+ ## Demo
67
68
 
68
69
  ```bash
69
- # 单页模式(draw.io 直接加载在当前页面)
70
+ # Single-page mode (draw.io loaded directly in the current page)
70
71
  pnpm --filter @y-mxgraph/demo dev
71
72
 
72
- # iframe 模式(父页运行 WebRTC Provider,两个 iframe 各跑一套 draw.io + y-mxgraph,通过 postMessage 同步)
73
- # 访问 http://localhost:5173/iframe-mode.html
73
+ # iframe mode (parent page runs WebRTC Provider, two iframes each run draw.io + y-mxgraph, synced via postMessage)
74
+ # Visit http://localhost:5173/iframe-mode.html
75
+
76
+ # WebSocket server mode (centralized server with file persistence)
77
+ pnpm --filter @y-mxgraph/ws-demo server # Start server on port 1234
78
+ pnpm --filter @y-mxgraph/ws-demo dev # Start client on port 5174
74
79
  ```
75
80
 
76
- # Docs
81
+ ## Docs
77
82
 
83
+ ```bash
78
84
  pnpm --filter @y-mxgraph/docs dev
79
-
80
85
  ```
81
86
 
82
87
  ## License
package/README.zh-CN.md CHANGED
@@ -63,9 +63,13 @@ pnpm --filter y-mxgraph build
63
63
  # 测试
64
64
  pnpm --filter y-mxgraph test
65
65
 
66
- # 启动 Demo
66
+ # 启动 Demo (WebRTC 模式)
67
67
  pnpm --filter @y-mxgraph/demo dev
68
68
 
69
+ # 启动 WebSocket 服务器 Demo (支持文件持久化)
70
+ pnpm --filter @y-mxgraph/ws-demo server # 启动服务器 (端口 1234)
71
+ pnpm --filter @y-mxgraph/ws-demo dev # 启动客户端 (端口 5174)
72
+
69
73
  # 启动文档
70
74
  pnpm --filter @y-mxgraph/docs dev
71
75
  ```
@@ -13,6 +13,11 @@ export interface BindDrawioFileOptions {
13
13
  }
14
14
  /**
15
15
  * Y-MXGraph 绑定类,管理 draw.io 文件与 Y.Doc 的双向同步
16
+ *
17
+ * 初始化流程对齐 y-prosemirror 等数据源:
18
+ * - 绑定时不向 Y.Doc 写入初始数据
19
+ * - 在第一次本地编辑时才初始化 Y.Doc
20
+ * - 新客户端加入时,同步已有的远端数据到本地
16
21
  */
17
22
  export declare class Binding {
18
23
  /** Y.Doc 实例,用于协同数据存储 */
@@ -21,6 +26,8 @@ export declare class Binding {
21
26
  private mxGraphModel;
22
27
  /** 本地变更抑制标志,防止循环同步 */
23
28
  private suppressLocalApply;
29
+ /** 初始化标志,标记 Y.Doc 是否已初始化 */
30
+ private docInitialized;
24
31
  /** mxGraph change 事件监听器 */
25
32
  private mxListener;
26
33
  /** Yjs 文档深度变更监听器 */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/binding/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAOvD,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,iBAAiB,CAAC;AAEhE,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EACH,OAAO,GACP;QACE,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACP;AAED;;GAEG;AACH,qBAAa,OAAO;IAClB,wBAAwB;IACxB,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;IACpB,6BAA6B;IAC7B,OAAO,CAAC,YAAY,CAAe;IACnC,sBAAsB;IACtB,OAAO,CAAC,kBAAkB,CAAS;IACnC,2BAA2B;IAC3B,OAAO,CAAC,UAAU,CAAa;IAC/B,oBAAoB;IACpB,OAAO,CAAC,WAAW,CAKT;IACV,gCAAgC;IAChC,OAAO,CAAC,mBAAmB,CAAC,CAAa;IACzC,yBAAyB;IACzB,OAAO,CAAC,kBAAkB,CAAC,CAAa;gBAE5B,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,qBAAqB;IAkF5D;;;OAGG;IACH,OAAO,CAAC,IAAI,UAAQ,GAAG,IAAI;IAS3B;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,oBAAoB,CAAC,SAAS,SAAc,GAAG,MAAM;IAa5D;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO;CAGzE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/binding/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AACzB,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAOvD,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,iBAAiB,CAAC;AAEhE,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,MAAM,CAAC,EACH,OAAO,GACP;QACE,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;CACP;AAED;;;;;;;GAOG;AACH,qBAAa,OAAO;IAClB,wBAAwB;IACxB,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC;IACpB,6BAA6B;IAC7B,OAAO,CAAC,YAAY,CAAe;IACnC,sBAAsB;IACtB,OAAO,CAAC,kBAAkB,CAAS;IACnC,4BAA4B;IAC5B,OAAO,CAAC,cAAc,CAAS;IAC/B,2BAA2B;IAC3B,OAAO,CAAC,UAAU,CAAa;IAC/B,oBAAoB;IACpB,OAAO,CAAC,WAAW,CAKT;IACV,gCAAgC;IAChC,OAAO,CAAC,mBAAmB,CAAC,CAAa;IACzC,yBAAyB;IACzB,OAAO,CAAC,kBAAkB,CAAC,CAAa;gBAE5B,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,qBAAqB;IA4G5D;;;OAGG;IACH,OAAO,CAAC,IAAI,UAAQ,GAAG,IAAI;IAS3B;;;;;;;;;;;;;;OAcG;IACH,MAAM,CAAC,oBAAoB,CAAC,SAAS,SAAc,GAAG,MAAM;IAa5D;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,qBAAqB,GAAG,OAAO;CAGzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../../src/binding/patch.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,QAAQ,EACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,KAAK,OAAO,EAEb,MAAM,kBAAkB,CAAC;AAO1B,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,QAAA,MAAM,WAAW,MAAM,CAAC;AACxB,QAAA,MAAM,WAAW,MAAM,CAAC;AACxB,QAAA,MAAM,WAAW,MAAM,CAAC;AAgDxB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC;IAChC,CAAC,WAAW,CAAC,CAAC,EAAE;QACd,CAAC,GAAG,EAAE,MAAM,GAAG;YACb,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,KAAK,CAAC,EAAE;gBACN,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;gBACzB,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;gBACzC,CAAC,WAAW,CAAC,CAAC,EAAE;oBACd,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;iBACvC,CAAC;aACH,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,QAqR/B;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,aAAa,UAAQ,QAsDhE;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,CACd,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,QAAQ,CAC1E,EAAE,EACH,WAAW,CAAC,EAAE,CAAC,CAAC,GAAG,GAClB,SAAS,CAgSX"}
1
+ {"version":3,"file":"patch.d.ts","sourceRoot":"","sources":["../../src/binding/patch.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,QAAQ,EACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEL,KAAK,OAAO,EAEb,MAAM,kBAAkB,CAAC;AAO1B,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,QAAA,MAAM,WAAW,MAAM,CAAC;AACxB,QAAA,MAAM,WAAW,MAAM,CAAC;AACxB,QAAA,MAAM,WAAW,MAAM,CAAC;AAgDxB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,CAAC,WAAW,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC;IAChC,CAAC,WAAW,CAAC,CAAC,EAAE;QACd,CAAC,GAAG,EAAE,MAAM,GAAG;YACb,IAAI,CAAC,EAAE,MAAM,CAAC;YACd,QAAQ,CAAC,EAAE,MAAM,CAAC;YAClB,KAAK,CAAC,EAAE;gBACN,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;gBACzB,CAAC,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;gBACzC,CAAC,WAAW,CAAC,CAAC,EAAE;oBACd,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;iBACvC,CAAC;aACH,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,QA8R/B;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,aAAa,UAAQ,QAyDhE;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,CAAC,CAAC,MAAM,CACd,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,QAAQ,CAC1E,EAAE,EACH,WAAW,CAAC,EAAE,CAAC,CAAC,GAAG,GAClB,SAAS,CAoSX"}
@@ -1 +1 @@
1
- {"version":3,"file":"mxCell.d.ts","sourceRoot":"","sources":["../../src/models/mxCell.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,eAAO,MAAM,GAAG,WAAW,CAAC;AAE5B,QAAA,MAAM,aAAa,eAAe,CAAC;AAGnC,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD,CAAC,aAAa,CAAC,CAAC,EAAE,cAAc,CAAC;CAClC;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,CAAC,UAAU,CAoBvD;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,2BA8BjD"}
1
+ {"version":3,"file":"mxCell.d.ts","sourceRoot":"","sources":["../../src/models/mxCell.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,eAAO,MAAM,GAAG,WAAW,CAAC;AAE5B,QAAA,MAAM,aAAa,eAAe,CAAC;AAGnC,MAAM,WAAW,WAAY,SAAQ,cAAc;IACjD,CAAC,aAAa,CAAC,CAAC,EAAE,cAAc,CAAC;CAClC;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,CAAC,UAAU,CAoBvD;AAED,wBAAgB,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,2BAmDjD"}
@@ -1 +1 @@
1
- {"version":3,"file":"mxfile.d.ts","sourceRoot":"","sources":["../../src/models/mxfile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAMzB,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,eAAO,MAAM,GAAG,WAAW,CAAC;AAC5B,eAAO,MAAM,eAAe,QAAuB,CAAC;AAEpD,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAErC,MAAM,WAAW,MAAO,SAAQ,cAAc;IAC5C,OAAO,EAAE,OAAO,EAAE,CAAC;CACpB;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,kBAkB/C;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CAgB3D"}
1
+ {"version":3,"file":"mxfile.d.ts","sourceRoot":"","sources":["../../src/models/mxfile.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAMzB,OAAO,KAAK,EAAE,OAAO,EAAY,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAE7C,eAAO,MAAM,GAAG,WAAW,CAAC;AAC5B,eAAO,MAAM,eAAe,QAAuB,CAAC;AAEpD,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAErC,MAAM,WAAW,MAAO,SAAQ,cAAc;IAC5C,OAAO,EAAE,OAAO,EAAE,CAAC;CACpB;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,kBAkB/C;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,CAqB3D"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "y-mxgraph",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Yjs binding for draw.io (mxGraph) documents",
5
5
  "keywords": [
6
6
  "yjs",
package/y-mxgraph.cjs.js CHANGED
@@ -85,12 +85,24 @@ function parse$3(object) {
85
85
  return xmlElement;
86
86
  }
87
87
  function serialize$2(xmlElement) {
88
- const attributes = {
88
+ const rawAttributes = {
89
89
  ...xmlElement.getAttributes()
90
90
  };
91
91
  let mxGeometry = null;
92
- if (mxGeometryAttributeKey in attributes) {
93
- const mxGeometryString = attributes[mxGeometryAttributeKey];
92
+ let mxGeometryString;
93
+ if (mxGeometryAttributeKey in rawAttributes) {
94
+ mxGeometryString = rawAttributes[mxGeometryAttributeKey];
95
+ delete rawAttributes[mxGeometryAttributeKey];
96
+ }
97
+ const attributes = {};
98
+ for (const [key2, value] of Object.entries(rawAttributes)) {
99
+ if (typeof value === "string") {
100
+ attributes[key2] = value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
101
+ } else if (value != null) {
102
+ attributes[key2] = String(value);
103
+ }
104
+ }
105
+ if (mxGeometryString) {
94
106
  try {
95
107
  const parsed = xmlJs.xml2js(mxGeometryString, { compact: true });
96
108
  mxGeometry = parsed[mxGeometryKey] ?? null;
@@ -100,7 +112,6 @@ function serialize$2(xmlElement) {
100
112
  } catch (e) {
101
113
  console.warn("[y-mxgraph] Failed to parse mxGeometry:", e);
102
114
  }
103
- delete attributes[mxGeometryAttributeKey];
104
115
  }
105
116
  const obj = {
106
117
  _attributes: attributes
@@ -189,11 +200,13 @@ function serializer(yMxFile) {
189
200
  const diagramOrder = yMxFile.get(
190
201
  diagramOrderKey
191
202
  );
203
+ const orderIds = diagramOrder ? diagramOrder.toArray() : [];
204
+ const ids = orderIds.length > 0 ? orderIds : diagrams ? Array.from(diagrams.keys()) : [];
192
205
  const obj = {
193
206
  _attributes: {
194
207
  pages: yMxFile.get("pages") || "1"
195
208
  },
196
- [key$1]: diagramOrder.map((id) => diagrams.get(id)).map((diagramElement) => serialize(diagramElement))
209
+ [key$1]: ids.map((id) => diagrams.get(id)).filter((d) => !!d).map((diagramElement) => serialize(diagramElement))
197
210
  };
198
211
  return obj;
199
212
  }
@@ -259,6 +272,12 @@ function applyFilePatch(doc, patch, options) {
259
272
  diagramOrderKey
260
273
  );
261
274
  ensureUniqueOrder(orderArr);
275
+ const currentOrder = orderArr.toArray();
276
+ if (currentOrder.length === 0 && diagramsMap && diagramsMap.size > 0) {
277
+ const allIds = Array.from(diagramsMap.keys());
278
+ orderArr.push(allIds);
279
+ }
280
+ ensureUniqueOrder(orderArr);
262
281
  const existingIds = orderArr.toArray();
263
282
  const existingIndex = /* @__PURE__ */ new Map();
264
283
  existingIds.forEach((id, idx) => existingIndex.set(id, idx));
@@ -478,7 +497,9 @@ function initDocSnapshot(doc, resetSnapshot = false) {
478
497
  const mxfile = doc.getMap(key);
479
498
  const diagramsMap = mxfile.get(key$1);
480
499
  const orderArr = mxfile.get(diagramOrderKey);
481
- const diagramOrder = resetSnapshot ? [] : orderArr ? orderArr.toArray().slice() : [];
500
+ const orderIds = orderArr ? orderArr.toArray() : [];
501
+ const allDiagramIds = orderIds.length > 0 ? orderIds : diagramsMap ? Array.from(diagramsMap.keys()) : [];
502
+ const diagramOrder = resetSnapshot ? [] : allDiagramIds.slice();
482
503
  const snap = {
483
504
  diagramOrder,
484
505
  cellsOrder: /* @__PURE__ */ new Map(),
@@ -551,7 +572,8 @@ function generatePatch(events, explicitDoc) {
551
572
  u.cells = u.cells || {};
552
573
  return u.cells;
553
574
  };
554
- const currDiagramOrder = orderArr.toArray();
575
+ const orderIds = orderArr.toArray();
576
+ const currDiagramOrder = orderIds.length > 0 ? orderIds : diagramsMap ? Array.from(diagramsMap.keys()) : [];
555
577
  const diagramsList = currDiagramOrder.map((id) => diagramsMap.get(id)).filter((d) => !!d);
556
578
  const currCellsOrder = /* @__PURE__ */ new Map();
557
579
  const cellAttrMap = /* @__PURE__ */ new Map();
@@ -1436,16 +1458,29 @@ function bindCollaborator(file, options) {
1436
1458
  class Binding {
1437
1459
  constructor(file, options) {
1438
1460
  this.suppressLocalApply = false;
1461
+ this.docInitialized = false;
1439
1462
  const { doc, awareness, undoManager, mouseMoveThrottle, cursor } = options;
1440
1463
  this.doc = doc;
1441
1464
  const ui = file.getUi();
1442
1465
  const graph = ui.editor.graph;
1443
1466
  this.mxGraphModel = graph.model;
1444
- const docHasData = doc.share.has(key);
1445
- if (!docHasData) {
1446
- xml2doc(file.data, doc);
1467
+ const mxfileMap = doc.getMap(key);
1468
+ const docHasData = mxfileMap.size > 0;
1469
+ this.docInitialized = docHasData;
1470
+ file.setShadowPages(file.ui.clonePages(file.ui.pages));
1471
+ if (docHasData) {
1472
+ initDocSnapshot(doc, false);
1473
+ const fullPatch = generatePatch([], doc);
1474
+ if (Object.keys(fullPatch).length > 0) {
1475
+ this.suppressLocalApply = true;
1476
+ try {
1477
+ file.patch([fullPatch]);
1478
+ } finally {
1479
+ this.suppressLocalApply = false;
1480
+ }
1481
+ }
1482
+ file.setShadowPages(file.ui.clonePages(file.ui.pages));
1447
1483
  }
1448
- initDocSnapshot(doc, docHasData);
1449
1484
  this.mxListener = () => {
1450
1485
  if (this.suppressLocalApply)
1451
1486
  return;
@@ -1453,16 +1488,31 @@ class Binding {
1453
1488
  file.shadowPages,
1454
1489
  file.ui.pages
1455
1490
  );
1491
+ const patchKeys = Object.keys(patch);
1492
+ if (patchKeys.length === 0)
1493
+ return;
1494
+ if (!this.docInitialized) {
1495
+ doc.transact(() => {
1496
+ xml2doc(file.data, doc);
1497
+ initDocSnapshot(doc, false);
1498
+ });
1499
+ this.docInitialized = true;
1500
+ }
1456
1501
  file.setShadowPages(file.ui.clonePages(file.ui.pages));
1457
1502
  applyFilePatch(doc, patch, { origin: LOCAL_ORIGIN });
1458
1503
  };
1459
1504
  this.mxGraphModel.addListener("change", this.mxListener);
1460
1505
  this.docObserver = (events, transaction) => {
1506
+ if (!this.docInitialized) {
1507
+ this.docInitialized = true;
1508
+ }
1461
1509
  if (transaction.local && transaction.origin === LOCAL_ORIGIN) {
1462
1510
  generatePatch(events);
1463
1511
  return;
1464
1512
  }
1465
1513
  const patch = generatePatch(events);
1514
+ if (Object.keys(patch).length === 0)
1515
+ return;
1466
1516
  this.suppressLocalApply = true;
1467
1517
  try {
1468
1518
  file.patch([patch]);
@@ -1471,19 +1521,7 @@ class Binding {
1471
1521
  this.suppressLocalApply = false;
1472
1522
  }
1473
1523
  };
1474
- doc.getMap(key).observeDeep(this.docObserver);
1475
- if (docHasData) {
1476
- const fullPatch = generatePatch([], doc);
1477
- if (Object.keys(fullPatch).length > 0) {
1478
- this.suppressLocalApply = true;
1479
- try {
1480
- file.patch([fullPatch]);
1481
- file.setShadowPages(file.ui.clonePages(file.ui.pages));
1482
- } finally {
1483
- this.suppressLocalApply = false;
1484
- }
1485
- }
1486
- }
1524
+ mxfileMap.observeDeep(this.docObserver);
1487
1525
  if (awareness) {
1488
1526
  this.cleanupCollaborator = bindCollaborator(file, {
1489
1527
  awareness,