y-mxgraph 0.8.6 → 0.9.0
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/consistency.d.ts +56 -0
- package/binding/consistency.d.ts.map +1 -0
- package/binding/index.d.ts +38 -0
- package/binding/index.d.ts.map +1 -1
- package/binding/patch.d.ts +4 -2
- package/binding/patch.d.ts.map +1 -1
- package/iframe-bridge/provider.cjs +27 -4
- package/iframe-bridge/provider.cjs.map +1 -1
- package/iframe-bridge/provider.js +25 -2
- package/iframe-bridge/provider.js.map +1 -1
- package/iframe-bridge/server.cjs +35 -11
- package/iframe-bridge/server.cjs.map +1 -1
- package/iframe-bridge/server.js +27 -3
- package/iframe-bridge/server.js.map +1 -1
- package/{index-BhW4J2Zt.js → index-CN7tFgEG.js} +26 -4
- package/index-CN7tFgEG.js.map +1 -0
- package/{index-D3Hk2QcW.cjs → index-CqD1uLD3.cjs} +24 -2
- package/index-CqD1uLD3.cjs.map +1 -0
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/models/mxGraphModel.d.ts.map +1 -1
- package/origin-C_FHB48F.cjs +6 -0
- package/origin-C_FHB48F.cjs.map +1 -0
- package/origin-Doo2uLkM.js +7 -0
- package/origin-Doo2uLkM.js.map +1 -0
- package/package.json +1 -1
- package/transform.cjs +1 -1
- package/transform.js +1 -1
- package/y-mxgraph.cjs +366 -143
- package/y-mxgraph.cjs.map +1 -1
- package/y-mxgraph.js +366 -143
- package/y-mxgraph.js.map +1 -1
- package/index-BhW4J2Zt.js.map +0 -1
- package/index-D3Hk2QcW.cjs.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as Y from "yjs";
|
|
2
|
+
/**
|
|
3
|
+
* Drift 检测事件。当 ydoc 与 file XML 检测到不一致时触发。
|
|
4
|
+
*/
|
|
5
|
+
export interface DriftEvent {
|
|
6
|
+
timestamp: number;
|
|
7
|
+
/** 检测来源 */
|
|
8
|
+
source: "binding" | "iframe-server" | "iframe-provider";
|
|
9
|
+
/** 不一致方向(基于检测时的状态推断) */
|
|
10
|
+
direction: "ydoc-ahead" | "file-ahead" | "unknown";
|
|
11
|
+
/** 详情描述 */
|
|
12
|
+
details?: string;
|
|
13
|
+
}
|
|
14
|
+
export type DriftHandler = (event: DriftEvent) => void;
|
|
15
|
+
/**
|
|
16
|
+
* 轻量级一致性检查:比较 ydoc 序列化后的 XML 与 file.data 是否等价。
|
|
17
|
+
*
|
|
18
|
+
* 由于 draw.io 内部可能添加编辑器状态属性(如 background 标记),这里
|
|
19
|
+
* 做结构级比较而非严格字符串等价。
|
|
20
|
+
*
|
|
21
|
+
* @returns true 表示一致,false 表示存在 drift
|
|
22
|
+
*/
|
|
23
|
+
export declare function checkConsistency(doc: Y.Doc, fileData: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* 一致性检查器,管理定时检测和 DriftEvent 分发。
|
|
26
|
+
*/
|
|
27
|
+
export declare class ConsistencyChecker {
|
|
28
|
+
private doc;
|
|
29
|
+
private getFileData;
|
|
30
|
+
private intervalId;
|
|
31
|
+
private handlers;
|
|
32
|
+
private consecutiveDriftCount;
|
|
33
|
+
private readonly maxAutoFixAttempts;
|
|
34
|
+
private source;
|
|
35
|
+
constructor(doc: Y.Doc, getFileData: () => string, options?: {
|
|
36
|
+
source?: DriftEvent["source"];
|
|
37
|
+
maxAutoFixAttempts?: number;
|
|
38
|
+
});
|
|
39
|
+
/** 注册 drift 事件监听 */
|
|
40
|
+
onDrift(handler: DriftHandler): () => void;
|
|
41
|
+
/** 启动定期检查(毫秒间隔),0 或负数表示禁用 */
|
|
42
|
+
start(intervalMs: number): void;
|
|
43
|
+
/** 停止定期检查 */
|
|
44
|
+
stop(): void;
|
|
45
|
+
/**
|
|
46
|
+
* 执行一次一致性检查。
|
|
47
|
+
* @returns true = 一致,false = 存在 drift
|
|
48
|
+
*/
|
|
49
|
+
check(): boolean;
|
|
50
|
+
/** 重置连续 drift 计数(forceSync 成功后调用) */
|
|
51
|
+
resetDriftCount(): void;
|
|
52
|
+
/** 是否已超过最大自动修复次数 */
|
|
53
|
+
get shouldStopAutoFix(): boolean;
|
|
54
|
+
destroy(): void;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=consistency.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consistency.d.ts","sourceRoot":"","sources":["../../src/binding/consistency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW;IACX,MAAM,EAAE,SAAS,GAAG,eAAe,GAAG,iBAAiB,CAAC;IACxD,wBAAwB;IACxB,SAAS,EAAE,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;IACnD,WAAW;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAEvD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAwBtE;AAED;;GAEG;AACH,qBAAa,kBAAkB;IAQ3B,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,WAAW;IARrB,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,MAAM,CAAuB;gBAG3B,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,WAAW,EAAE,MAAM,MAAM,EACjC,OAAO,GAAE;QACP,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;KACxB;IAMR,oBAAoB;IACpB,OAAO,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,IAAI;IAK1C,6BAA6B;IAC7B,KAAK,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAQ/B,aAAa;IACb,IAAI,IAAI,IAAI;IAOZ;;;OAGG;IACH,KAAK,IAAI,OAAO;IA2BhB,qCAAqC;IACrC,eAAe,IAAI,IAAI;IAIvB,oBAAoB;IACpB,IAAI,iBAAiB,IAAI,OAAO,CAE/B;IAED,OAAO,IAAI,IAAI;CAIhB"}
|
package/binding/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as Y from "yjs";
|
|
2
2
|
import { type Awareness } from "y-protocols/awareness";
|
|
3
3
|
import type { DrawioFile } from "../types/drawio";
|
|
4
|
+
import { type DriftHandler } from "./consistency";
|
|
5
|
+
export type { DriftEvent, DriftHandler } from "./consistency";
|
|
4
6
|
/**
|
|
5
7
|
* 控制 Binding 构造时 file 与 Y.Doc 的初始内容对齐策略。
|
|
6
8
|
* - `replace` : doc 非空则用 doc 覆盖 file;doc 为空则保留 file 现有数据(默认)。
|
|
@@ -60,6 +62,20 @@ export interface BindDrawioFileOptions {
|
|
|
60
62
|
* 适用于异步资源处理场景(如图片上传),可精确过滤包含中间态的 cell 变更。
|
|
61
63
|
*/
|
|
62
64
|
transformPatch?: (patch: import("./patch").FilePatch) => import("./patch").FilePatch | null | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* 一致性检查间隔(毫秒)。设为 0 或不传则禁用定期检查。
|
|
67
|
+
* 检测到 ydoc 与 file XML 不一致时会触发 drift 事件。
|
|
68
|
+
*/
|
|
69
|
+
consistencyCheckInterval?: number;
|
|
70
|
+
/**
|
|
71
|
+
* drift 事件回调。当一致性检测发现 ydoc 与 file 不一致时触发。
|
|
72
|
+
*/
|
|
73
|
+
onDrift?: DriftHandler;
|
|
74
|
+
/**
|
|
75
|
+
* patch 后检查顺序一致性,不一致时自动 forceSync。
|
|
76
|
+
* 默认 `false`。设为 `true` 可启用保底机制。
|
|
77
|
+
*/
|
|
78
|
+
syncOnOrderMismatch?: boolean;
|
|
63
79
|
}
|
|
64
80
|
/**
|
|
65
81
|
* Y-MXGraph 绑定类,管理 draw.io 文件与 Y.Doc 的双向同步
|
|
@@ -94,6 +110,14 @@ export declare class Binding {
|
|
|
94
110
|
private ui;
|
|
95
111
|
/** 转换本地 patch 的回调 */
|
|
96
112
|
private transformPatch?;
|
|
113
|
+
/** 一致性检查器 */
|
|
114
|
+
private consistencyChecker?;
|
|
115
|
+
/** applyFileData 回调引用(forceSync 需要) */
|
|
116
|
+
private applyFileData;
|
|
117
|
+
/** debounce 后的 forceSync,用于 patch 后保底 */
|
|
118
|
+
private debouncedForceSync;
|
|
119
|
+
/** patch 后检查顺序一致性 */
|
|
120
|
+
private syncOnOrderMismatch;
|
|
97
121
|
/** replace 策略下,构造时 doc 为空,现在 doc 有数据时需要强制替换 */
|
|
98
122
|
private get shouldReplaceWhenDocHasData();
|
|
99
123
|
constructor(file: DrawioFile, options: BindDrawioFileOptions);
|
|
@@ -102,6 +126,20 @@ export declare class Binding {
|
|
|
102
126
|
* Yjs 接管持久化后,draw.io 的原生保存状态不再有意义。
|
|
103
127
|
*/
|
|
104
128
|
private resetEditorStatus;
|
|
129
|
+
/**
|
|
130
|
+
* 强制同步 ydoc 与 file,修复检测到的不一致。
|
|
131
|
+
*
|
|
132
|
+
* @param direction - 同步方向
|
|
133
|
+
* - `ydoc-to-file`(默认):用 ydoc 数据覆盖 file
|
|
134
|
+
* - `file-to-ydoc`:用 file 数据覆盖 ydoc
|
|
135
|
+
*/
|
|
136
|
+
forceSync(direction?: "ydoc-to-file" | "file-to-ydoc"): void;
|
|
137
|
+
private checkOrderMismatch;
|
|
138
|
+
/**
|
|
139
|
+
* 手动触发一次一致性检查。
|
|
140
|
+
* @returns true = 一致,false = 存在 drift
|
|
141
|
+
*/
|
|
142
|
+
checkConsistency(): boolean;
|
|
105
143
|
/**
|
|
106
144
|
* 销毁绑定,解除所有监听器
|
|
107
145
|
* @param deep - 是否深度清理(包括 awareness/undoManager),默认 false
|
package/binding/index.d.ts.map
CHANGED
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/binding/index.ts"],"names":[],"mappings":"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"}
|
package/binding/patch.d.ts
CHANGED
|
@@ -7,7 +7,8 @@ declare const DIFF_UPDATE = "u";
|
|
|
7
7
|
export interface DiagramInsert {
|
|
8
8
|
data: string;
|
|
9
9
|
id: string;
|
|
10
|
-
previous
|
|
10
|
+
/** previous 语义:"" = 最前面,null/undefined = 未找到,string = 在该 id 之后 */
|
|
11
|
+
previous?: string | null;
|
|
11
12
|
}
|
|
12
13
|
export interface FilePatch {
|
|
13
14
|
[DIFF_REMOVE]?: string[];
|
|
@@ -15,7 +16,8 @@ export interface FilePatch {
|
|
|
15
16
|
[DIFF_UPDATE]?: {
|
|
16
17
|
[key: string]: {
|
|
17
18
|
name?: string;
|
|
18
|
-
previous
|
|
19
|
+
/** previous 语义:"" = 最前面,null = 未找到,string = 在该 id 之后 */
|
|
20
|
+
previous?: string | null;
|
|
19
21
|
/** draw.io page viewState(如 background),与 diffPages 格式一致 */
|
|
20
22
|
view?: Record<string, string>;
|
|
21
23
|
cells?: {
|
package/binding/patch.d.ts.map
CHANGED
|
@@ -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;AAa1B,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,QAAA,MAAM,WAAW,MAAM,CAAC;AACxB,QAAA,MAAM,WAAW,MAAM,CAAC;AACxB,QAAA,MAAM,WAAW,MAAM,CAAC;
|
|
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;AAa1B,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,QAAA,MAAM,WAAW,MAAM,CAAC;AACxB,QAAA,MAAM,WAAW,MAAM,CAAC;AACxB,QAAA,MAAM,WAAW,MAAM,CAAC;AA2DxB,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,kEAAkE;IAClE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;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,wDAAwD;YACxD,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACzB,4DAA4D;YAC5D,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC9B,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;AAmCD,wBAAgB,cAAc,CAC5B,GAAG,EAAE,CAAC,CAAC,GAAG,EACV,KAAK,EAAE,SAAS,EAChB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,QAoV/B;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,aAAa,UAAQ,QA2DhE;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,CA2UX"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const Y = require("yjs");
|
|
4
4
|
const awareness = require("y-protocols/awareness");
|
|
5
|
+
const origin = require("../origin-C_FHB48F.cjs");
|
|
5
6
|
function _interopNamespaceDefault(e) {
|
|
6
7
|
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
7
8
|
if (e) {
|
|
@@ -145,7 +146,7 @@ function parseAwarenessPayload(data) {
|
|
|
145
146
|
return result;
|
|
146
147
|
}
|
|
147
148
|
function createIframeBridgeProvider(ydoc, options) {
|
|
148
|
-
const { awareness: externalAwareness, debug = false } = options != null ? options : {};
|
|
149
|
+
const { awareness: externalAwareness, debug = false, consistencyCheckInterval = 0 } = options != null ? options : {};
|
|
149
150
|
let applyingParentUpdate = false;
|
|
150
151
|
let serverClientId = null;
|
|
151
152
|
let currentCleanup = null;
|
|
@@ -158,6 +159,7 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
158
159
|
let seq = 0;
|
|
159
160
|
const unackedYdocUpdates = /* @__PURE__ */ new Map();
|
|
160
161
|
let initRetryTimer = null;
|
|
162
|
+
let consistencyTimer = null;
|
|
161
163
|
let serverSupportsAck = false;
|
|
162
164
|
let legacyMode = false;
|
|
163
165
|
const connectListeners = /* @__PURE__ */ new Set();
|
|
@@ -279,6 +281,7 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
279
281
|
}
|
|
280
282
|
}
|
|
281
283
|
connectListeners.forEach((fn) => fn());
|
|
284
|
+
startConsistencyCheck();
|
|
282
285
|
} else {
|
|
283
286
|
lastLocalAwarenessSnapshot = null;
|
|
284
287
|
if (!legacyMode) {
|
|
@@ -312,9 +315,19 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
312
315
|
}
|
|
313
316
|
}, 1e3);
|
|
314
317
|
}
|
|
315
|
-
|
|
318
|
+
function startConsistencyCheck() {
|
|
319
|
+
if (consistencyTimer) clearInterval(consistencyTimer);
|
|
320
|
+
if (consistencyCheckInterval <= 0) return;
|
|
321
|
+
consistencyTimer = setInterval(() => {
|
|
322
|
+
if (!connected) return;
|
|
323
|
+
const sv = Y__namespace.encodeStateVector(ydoc);
|
|
324
|
+
parentPostMessage({ type: "consistency-check", stateVector: Array.from(sv) });
|
|
325
|
+
log("consistency-check sent");
|
|
326
|
+
}, consistencyCheckInterval);
|
|
327
|
+
}
|
|
328
|
+
const onYdocUpdate = (update, origin2) => {
|
|
316
329
|
if (applyingParentUpdate) return;
|
|
317
|
-
const isBaseline =
|
|
330
|
+
const isBaseline = origin2 === null || origin2 === void 0;
|
|
318
331
|
if (!connected) {
|
|
319
332
|
if (pendingYdocUpdates.length >= MAX_QUEUE_SIZE) {
|
|
320
333
|
forceFullSync = true;
|
|
@@ -418,7 +431,9 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
418
431
|
}
|
|
419
432
|
if (type === "ydoc-sync" || type === "ydoc-update") {
|
|
420
433
|
applyingParentUpdate = true;
|
|
421
|
-
|
|
434
|
+
const isBaseline = event.data && typeof event.data === "object" && event.data.isBaseline ? true : false;
|
|
435
|
+
const applyOrigin = isBaseline ? origin.BASELINE_ORIGIN : origin.IFRAME_ORIGIN;
|
|
436
|
+
Y__namespace.applyUpdate(ydoc, new Uint8Array(payload), applyOrigin);
|
|
422
437
|
applyingParentUpdate = false;
|
|
423
438
|
if (type === "ydoc-sync" && event.data.protocolVersion != null) {
|
|
424
439
|
if (event.data.protocolVersion >= 2 && !serverSupportsAck) {
|
|
@@ -503,6 +518,10 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
503
518
|
} else if (type === "disconnect") {
|
|
504
519
|
setConnected(false);
|
|
505
520
|
startInitRetry();
|
|
521
|
+
} else if (type === "force-sync") {
|
|
522
|
+
log("received force-sync from server");
|
|
523
|
+
const fullState = Y__namespace.encodeStateAsUpdate(ydoc);
|
|
524
|
+
parentPostMessage({ type: "ydoc-pending-updates", payload: [{ update: Array.from(fullState), isBaseline: false }] });
|
|
506
525
|
}
|
|
507
526
|
};
|
|
508
527
|
ydoc.on("update", onYdocUpdate);
|
|
@@ -689,6 +708,10 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
689
708
|
clearInterval(initRetryTimer);
|
|
690
709
|
initRetryTimer = null;
|
|
691
710
|
}
|
|
711
|
+
if (consistencyTimer) {
|
|
712
|
+
clearInterval(consistencyTimer);
|
|
713
|
+
consistencyTimer = null;
|
|
714
|
+
}
|
|
692
715
|
connectListeners.clear();
|
|
693
716
|
disconnectListeners.clear();
|
|
694
717
|
if (currentCleanup) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.cjs","sources":["../../../iframe-bridge/src/provider.ts"],"sourcesContent":["import * as Y from \"yjs\";\nimport {\n Awareness,\n applyAwarenessUpdate,\n} from \"y-protocols/awareness\";\nconst IFRAME_BRIDGE_STATE_KEYS = new Set([\"cursor\", \"selection\"]);\n\nfunction isIframeBridgeStateKey(key: string): boolean {\n return IFRAME_BRIDGE_STATE_KEYS.has(key);\n}\n\nfunction getAwarenessStateFieldChanges(\n prev: Record<string, unknown> | null,\n next: Record<string, unknown> | null,\n): Array<{ key: string; value: unknown }> {\n const keys = new Set([\n ...Object.keys(prev ?? {}),\n ...Object.keys(next ?? {}),\n ]);\n const changes: Array<{ key: string; value: unknown }> = [];\n for (const key of keys) {\n const prevValue = prev?.[key];\n const nextValue = next?.[key];\n if (JSON.stringify(prevValue) !== JSON.stringify(nextValue)) {\n changes.push({ key, value: nextValue });\n }\n }\n return changes;\n}\n\n/**\n * Awareness-like 接口,只需要支持本地状态管理。\n * 用于 iframe-bridge provider 不需要与父页面同步 awareness 的场景。\n */\nexport interface AwarenessLike {\n readonly clientID: number;\n readonly states: Map<number, Record<string, unknown>>;\n getStates(): Map<number, Record<string, unknown>>;\n getLocalState(): Record<string, unknown> | null;\n setLocalState(state: Record<string, unknown> | null): void;\n setLocalStateField(field: string, value: unknown): void;\n on(event: \"update\", handler: (update: { added: number[]; updated: number[]; removed: number[] }) => void): void;\n off(event: \"update\", handler: (update: { added: number[]; updated: number[]; removed: number[] }) => void): void;\n}\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\ntype MxLike = Record<string, unknown> & {\n eventListeners: Array<string | ListenerFn>;\n history: unknown[];\n indexOfNextAdd: number;\n addListener(name: string, fn: ListenerFn): void;\n fireEvent(evt: unknown): void;\n canUndo(): boolean;\n canRedo(): boolean;\n undo(): void;\n redo(): void;\n undoableEditHappened(_edit: unknown): void;\n};\n\nexport interface DrawioEditor {\n undoManager?: {\n eventListeners?: unknown[];\n [key: string]: unknown;\n };\n undoListener?: (...args: unknown[]) => void;\n}\n\nexport interface DrawioFile {\n getUi(): { editor: DrawioEditor };\n}\n\nexport interface IframeBridgeProviderOptions {\n awareness?: Awareness;\n debug?: boolean;\n}\n\nexport interface IframeBridgeProvider {\n serverClientId: number | null;\n connected: boolean;\n awareness: Awareness;\n onConnect: (fn: () => void) => () => void;\n onDisconnect: (fn: () => void) => () => void;\n on: (event: \"connect\" | \"disconnect\", fn: () => void) => () => void;\n setLocalFields: (fields: Record<string, unknown>) => void;\n takeoverUndoManager: (file: DrawioFile) => () => void;\n destroy: () => void;\n}\n\nfunction readVarUint(data: Uint8Array, pos: number): [number, number] {\n let result = 0;\n let shift = 0;\n let byte: number;\n do {\n byte = data[pos++];\n result |= (byte & 0x7f) << shift;\n shift += 7;\n } while (byte >= 0x80);\n return [result >>> 0, pos];\n}\n\nfunction writeVarUint(value: number): number[] {\n const bytes: number[] = [];\n while (value > 0x7f) {\n bytes.push((value & 0x7f) | 0x80);\n value >>>= 7;\n }\n bytes.push(value);\n return bytes;\n}\n\nfunction readVarString(data: Uint8Array, pos: number): [string, number] {\n const [len, pos2] = readVarUint(data, pos);\n const str = new TextDecoder().decode(data.subarray(pos2, pos2 + len));\n return [str, pos2 + len];\n}\n\nfunction writeVarString(str: string): number[] {\n const encoded = new TextEncoder().encode(str);\n return [...writeVarUint(encoded.length), ...encoded];\n}\n\nfunction remapClientIdInUpdate(\n update: Uint8Array,\n fromId: number,\n toId: number,\n): Uint8Array {\n const entries: Array<{ clientID: number; clock: number; state: string }> = [];\n const seenClientIds = new Set<number>();\n let pos = 0;\n\n const [count, pos2] = readVarUint(update, pos);\n pos = pos2;\n\n for (let i = 0; i < count; i++) {\n const [clientID, pos3] = readVarUint(update, pos);\n pos = pos3;\n const [clock, pos4] = readVarUint(update, pos);\n pos = pos4;\n const [state, pos5] = readVarString(update, pos);\n pos = pos5;\n\n const mappedId = clientID === fromId ? toId : clientID;\n if (seenClientIds.has(mappedId)) {\n continue;\n }\n\n seenClientIds.add(mappedId);\n entries.push({ clientID: mappedId, clock, state });\n }\n\n const result: number[] = [];\n result.push(...writeVarUint(entries.length));\n for (const entry of entries) {\n result.push(...writeVarUint(entry.clientID));\n result.push(...writeVarUint(entry.clock));\n result.push(...writeVarString(entry.state));\n }\n\n return new Uint8Array(result);\n}\n\nfunction parseAwarenessPayload(data: Uint8Array): Map<number, Record<string, unknown>> {\n const result = new Map<number, Record<string, unknown>>();\n let pos = 0;\n const [count, pos2] = readVarUint(data, pos);\n pos = pos2;\n\n for (let i = 0; i < count; i++) {\n const [clientID, pos3] = readVarUint(data, pos);\n pos = pos3;\n const [, pos4] = readVarUint(data, pos);\n pos = pos4;\n const [stateStr, pos5] = readVarString(data, pos);\n pos = pos5;\n\n if (stateStr) {\n try {\n result.set(clientID, JSON.parse(stateStr));\n } catch {\n // no-op\n }\n }\n }\n return result;\n}\n\nexport function createIframeBridgeProvider(\n ydoc: Y.Doc,\n options?: IframeBridgeProviderOptions,\n): IframeBridgeProvider {\n const { awareness: externalAwareness, debug = false } = options ?? {};\n let applyingParentUpdate = false;\n let serverClientId: number | null = null;\n let currentCleanup: (() => void) | null = null;\n let currentMxLike: MxLike | null = null;\n let pendingUndoState: {\n undoStackSize?: number;\n redoStackSize?: number;\n } | null = null;\n let connected = false;\n let forceFullSync = false;\n const MAX_QUEUE_SIZE = 1000;\n const pendingYdocUpdates: Array<{update: Uint8Array, isBaseline: boolean}> = [];\n let seq = 0;\n const unackedYdocUpdates = new Map<number, { update: Uint8Array; isBaseline: boolean }>();\n let initRetryTimer: ReturnType<typeof setInterval> | null = null;\n \n // Legacy mode detection: old servers don't send protocolVersion in pong\n let serverSupportsAck = false;\n let legacyMode = false;\n const connectListeners = new Set<() => void>();\n const disconnectListeners = new Set<() => void>();\n let lastLocalAwarenessSnapshot: Record<string, unknown> | null = null;\n\n const log = debug\n ? (...args: unknown[]) => console.log(\"[iframe-bridge provider]\", ...args)\n : () => undefined;\n\n const useExternalAwareness = !!externalAwareness;\n let awareness: Awareness | AwarenessLike;\n const localStates = new Map<number, Record<string, unknown>>();\n const localClientId = Math.floor(Math.random() * 2147483647) + 1;\n const updateHandlers = new Set<(update: { added: number[]; updated: number[]; removed: number[] }) => void>();\n\n function createAwarenessLike(): AwarenessLike {\n function getEffectiveClientId() {\n return serverClientId ?? localClientId;\n }\n\n return {\n get clientID() {\n return getEffectiveClientId();\n },\n get states() {\n return localStates;\n },\n getStates() {\n return new Map(localStates);\n },\n getLocalState() {\n return localStates.get(getEffectiveClientId()) ?? null;\n },\n setLocalState(state: Record<string, unknown> | null) {\n const id = getEffectiveClientId();\n if (state === null) {\n localStates.delete(id);\n const update = { added: [], updated: [], removed: [id] };\n updateHandlers.forEach(handler => handler(update));\n } else {\n const existed = localStates.has(id);\n localStates.set(id, state);\n const update = { added: !existed ? [id] : [], updated: [id], removed: [] };\n updateHandlers.forEach(handler => handler(update));\n }\n },\n setLocalStateField(field: string, value: unknown) {\n const id = getEffectiveClientId();\n const current = localStates.get(id) || {};\n const newState = { ...current, [field]: value };\n localStates.set(id, newState);\n postSetLocalStateToParent(field, value);\n const update = { added: [], updated: [id], removed: [] };\n updateHandlers.forEach(handler => handler(update));\n },\n on(event: \"update\", handler: (update: { added: number[]; updated: number[]; removed: number[] }) => void) {\n if (event === \"update\") {\n updateHandlers.add(handler);\n }\n },\n off(event: \"update\", handler: (update: { added: number[]; updated: number[]; removed: number[] }) => void) {\n if (event === \"update\") {\n updateHandlers.delete(handler);\n }\n },\n };\n }\n\n if (externalAwareness) {\n awareness = externalAwareness;\n } else {\n awareness = createAwarenessLike();\n }\n\n function formatPayload(payload: unknown) {\n if (payload instanceof Uint8Array) {\n return { bytes: payload.byteLength };\n }\n if (Array.isArray(payload) && payload.every((item) => typeof item === \"number\")) {\n return { bytes: payload.length };\n }\n return payload;\n }\n\n function logMessage(direction: \"send\" | \"recv\", type: string, payload?: unknown) {\n if (!debug) return;\n log(direction, type, formatPayload(payload));\n }\n\n function snapshotLocalAwarenessState() {\n const state = awareness.getLocalState();\n lastLocalAwarenessSnapshot = state ? { ...state } : null;\n }\n\n function postSetLocalStateToParent(key: string, value: unknown) {\n if (!connected || !isIframeBridgeStateKey(key)) return;\n const message = { type: \"set-local-state\", key, value };\n logMessage(\"send\", \"set-local-state\", message);\n window.parent.postMessage(message, \"*\");\n }\n\n function parentPostMessage(message: unknown) {\n logMessage(\"send\", (message as { type?: string }).type ?? \"postMessage\", message);\n window.parent.postMessage(message, \"*\");\n }\n\n function setConnected(value: boolean) {\n if (connected === value) return;\n connected = value;\n if (value) {\n forceFullSync = false;\n snapshotLocalAwarenessState();\n while (pendingYdocUpdates.length > 0) {\n const { update, isBaseline } = pendingYdocUpdates.shift()!;\n if (legacyMode) {\n const message = { type: \"ydoc-update\", payload: Array.from(update), isBaseline };\n window.parent.postMessage(message, \"*\");\n } else {\n const seqNum = ++seq;\n const message = { type: \"ydoc-update\", payload: Array.from(update), isBaseline, seq: seqNum };\n window.parent.postMessage(message, \"*\");\n unackedYdocUpdates.set(seqNum, { update, isBaseline });\n }\n }\n if (!legacyMode) {\n for (const [savedSeq, { update, isBaseline }] of unackedYdocUpdates) {\n const message = { type: \"ydoc-update\", payload: Array.from(update), isBaseline, seq: savedSeq };\n window.parent.postMessage(message, \"*\");\n }\n }\n connectListeners.forEach((fn) => fn());\n } else {\n lastLocalAwarenessSnapshot = null;\n if (!legacyMode) {\n unackedYdocUpdates.clear();\n }\n disconnectListeners.forEach((fn) => fn());\n }\n }\n\n function startInitRetry() {\n if (initRetryTimer) {\n clearInterval(initRetryTimer);\n }\n if (!forceFullSync && pendingYdocUpdates.length > 0) {\n if (!legacyMode) {\n const updates = pendingYdocUpdates.splice(0);\n parentPostMessage({\n type: \"ydoc-pending-updates\",\n payload: updates.map(u => ({ update: Array.from(u.update), isBaseline: u.isBaseline })),\n });\n } else {\n for (const { update, isBaseline } of pendingYdocUpdates) {\n parentPostMessage({ type: \"ydoc-update\", payload: Array.from(update), isBaseline });\n }\n pendingYdocUpdates.length = 0;\n }\n }\n parentPostMessage({ type: \"init\" });\n initRetryTimer = setInterval(() => {\n if (!connected) {\n parentPostMessage({ type: \"init\" });\n }\n }, 1000);\n }\n\n const onYdocUpdate = (update: Uint8Array, origin: unknown) => {\n if (applyingParentUpdate) return;\n // 检测基线数据:origin 为 null 时是 xml2ydoc 首次初始化\n const isBaseline = origin === null || origin === undefined;\n if (!connected) {\n if (pendingYdocUpdates.length >= MAX_QUEUE_SIZE) {\n forceFullSync = true;\n pendingYdocUpdates.length = 0;\n console.warn(\"[iframe-bridge] queue full, forcing full sync on reconnect\");\n }\n pendingYdocUpdates.push({ update, isBaseline });\n return;\n }\n if (legacyMode) {\n const message = { type: \"ydoc-update\", payload: Array.from(update), isBaseline };\n logMessage(\"send\", \"ydoc-update\", message);\n window.parent.postMessage(message, \"*\");\n } else {\n const seqNum = ++seq;\n const message = { type: \"ydoc-update\", payload: Array.from(update), isBaseline, seq: seqNum };\n logMessage(\"send\", \"ydoc-update\", message);\n window.parent.postMessage(message, \"*\");\n unackedYdocUpdates.set(seqNum, { update, isBaseline });\n }\n };\n\n const onAwarenessUpdate = ({\n added,\n updated,\n removed,\n }: {\n added: number[];\n updated: number[];\n removed: number[];\n }) => {\n if (applyingParentUpdate) {\n return;\n }\n if (!connected) {\n return;\n }\n const changes = [...added, ...updated, ...removed];\n if (changes.length === 0) return;\n\n const localClientId = awareness.clientID;\n const localChanged = changes.includes(localClientId);\n if (!localChanged) return;\n\n const nextState = awareness.getLocalState();\n const fieldChanges = getAwarenessStateFieldChanges(\n lastLocalAwarenessSnapshot,\n nextState,\n );\n lastLocalAwarenessSnapshot = nextState ? { ...nextState } : null;\n for (const { key, value } of fieldChanges) {\n postSetLocalStateToParent(key, value);\n }\n };\n\n const syncUndoStateFromServer = (\n mxLike: MxLike,\n data: { undoStackSize?: number; redoStackSize?: number },\n ) => {\n const { undoStackSize, redoStackSize } = data;\n const oldIndex = mxLike.indexOfNextAdd;\n const newIndex = undoStackSize || 0;\n const newTotal = (undoStackSize || 0) + (redoStackSize || 0);\n applyingParentUpdate = true;\n mxLike.history = new Array(newTotal).fill({});\n mxLike.indexOfNextAdd = newIndex;\n if (newTotal === 0) {\n mxLike.fireEvent(createMxEventObject(\"clear\"));\n } else if (newIndex < oldIndex) {\n mxLike.fireEvent(\n createMxEventObject(\"undo\", { edit: { changes: [] } }),\n );\n } else if (newIndex > oldIndex) {\n mxLike.fireEvent(\n createMxEventObject(\"redo\", { edit: { changes: [] } }),\n );\n } else {\n mxLike.fireEvent(\n createMxEventObject(\"add\", { edit: { changes: [] } }),\n );\n }\n applyingParentUpdate = false;\n };\n\n const onMessage = (event: MessageEvent) => {\n if (event.source !== window.parent) return;\n if (!event.data || typeof event.data !== 'object') return;\n const { type, payload, serverClientId: receivedServerId } = event.data;\n\n logMessage(\"recv\", type, payload);\n if (type === \"pong\" && receivedServerId != null) {\n serverClientId = receivedServerId;\n // 版本号检测:新版 server 在 pong 里带 protocolVersion\n if (event.data.protocolVersion >= 2) {\n serverSupportsAck = true;\n if (legacyMode) {\n // ydoc-sync 先到且无 protocolVersion 时误判了 legacy,纠正回来\n legacyMode = false;\n log(\"server supports ack (protocol v\" + event.data.protocolVersion + \", corrected from legacy)\");\n } else {\n log(\"server supports ack (protocol v\" + event.data.protocolVersion + \")\");\n }\n } else if (!serverSupportsAck) {\n legacyMode = true;\n unackedYdocUpdates.clear();\n log(\"legacy mode detected: server has no protocolVersion\");\n }\n return;\n }\n if (type === \"ydoc-update-ack\") {\n const ackSeq = event.data.seq;\n if (ackSeq != null) {\n unackedYdocUpdates.delete(ackSeq);\n }\n return;\n }\n\n if (type === \"ydoc-sync\" || type === \"ydoc-update\") {\n applyingParentUpdate = true;\n Y.applyUpdate(ydoc, new Uint8Array(payload));\n applyingParentUpdate = false;\n // ydoc-sync 也可能带 protocolVersion(兜底检测,正常情况 pong 已检测)\n if (type === \"ydoc-sync\" && event.data.protocolVersion != null) {\n if (event.data.protocolVersion >= 2 && !serverSupportsAck) {\n serverSupportsAck = true;\n log(\"server supports ack (protocol v\" + event.data.protocolVersion + \", via ydoc-sync)\");\n }\n } else if (type === \"ydoc-sync\" && !serverSupportsAck && !legacyMode) {\n // ydoc-sync 无 protocolVersion 且 pong 还没来 → 先切 legacy\n // 如果 pong 后来带 protocolVersion 会纠正回来\n legacyMode = true;\n unackedYdocUpdates.clear();\n log(\"legacy mode tentative: ydoc-sync has no protocolVersion\");\n }\n if (type === \"ydoc-sync\" && !connected) {\n setConnected(true);\n if (initRetryTimer) {\n clearInterval(initRetryTimer);\n initRetryTimer = null;\n }\n }\n } else if (type === \"awareness-sync\" || type === \"awareness-update\") {\n logMessage(\"recv\", type, payload);\n const prevLocalId = localClientId;\n if (receivedServerId != null) {\n serverClientId = receivedServerId;\n if (useExternalAwareness === false && receivedServerId != null && prevLocalId !== receivedServerId) {\n const tempState = localStates.get(prevLocalId);\n if (tempState) {\n localStates.delete(prevLocalId);\n localStates.set(receivedServerId, tempState);\n }\n }\n }\n\n if (useExternalAwareness) {\n const serverId = receivedServerId ?? serverClientId;\n const localId = awareness.clientID;\n \n applyingParentUpdate = true;\n if (serverId != null && serverId !== localId) {\n const remapped = remapClientIdInUpdate(\n new Uint8Array(payload),\n serverId,\n localId,\n );\n \n if (type === \"awareness-sync\") {\n (awareness as Awareness).meta.delete(localId);\n awareness.setLocalState(null);\n }\n \n applyAwarenessUpdate(awareness as Awareness, remapped, null);\n } else {\n applyAwarenessUpdate(awareness as Awareness, new Uint8Array(payload), null);\n }\n applyingParentUpdate = false;\n } else {\n const parsedStates = parseAwarenessPayload(new Uint8Array(payload));\n applyingParentUpdate = true;\n const changedClientIds: number[] = [];\n const removedClientIds: number[] = [];\n for (const [id, state] of parsedStates) {\n const existed = localStates.has(id);\n const changed = !existed || JSON.stringify(localStates.get(id)) !== JSON.stringify(state);\n localStates.set(id, state);\n if (changed) {\n changedClientIds.push(id);\n }\n }\n for (const [id] of localStates) {\n if (!parsedStates.has(id)) {\n localStates.delete(id);\n removedClientIds.push(id);\n }\n }\n if (changedClientIds.length > 0 || removedClientIds.length > 0) {\n const update = { added: [], updated: changedClientIds, removed: removedClientIds };\n updateHandlers.forEach(handler => handler(update));\n }\n applyingParentUpdate = false;\n }\n } else if (type === \"undo-state\") {\n if (!currentMxLike) {\n pendingUndoState = event.data;\n } else {\n syncUndoStateFromServer(currentMxLike, event.data);\n }\n } else if (type === \"disconnect\") {\n setConnected(false);\n startInitRetry();\n }\n };\n\n ydoc.on(\"update\", onYdocUpdate);\n // 只有真正的 y-protocols Awareness 实例才有 .on() 方法\n // AwarenessLike(内部创建的)通过 updateHandlers 管理回调\n if (useExternalAwareness) {\n (awareness as Awareness).on(\"update\", onAwarenessUpdate);\n }\n window.addEventListener(\"message\", onMessage);\n\n startInitRetry();\n\n // 发送 ping 获取 serverClientId\n setTimeout(() => {\n window.parent.postMessage({ type: \"ping\" }, \"*\");\n }, 100);\n\n return {\n get serverClientId() {\n return serverClientId;\n },\n get connected() {\n return connected;\n },\n get awareness() {\n return awareness as Awareness;\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 setLocalFields(fields: Record<string, unknown>) {\n const currentLocal = awareness.getLocalState() || {};\n const currentUser = (currentLocal as { user?: Record<string, unknown> }).user || {};\n const newUser = { ...currentUser, ...fields };\n awareness.setLocalState({\n ...currentLocal,\n user: newUser,\n });\n // 通知父页面更新本地字段,父页面可选择是否处理\n if (connected) {\n const message = { type: \"set-local-fields\", fields };\n logMessage(\"send\", \"set-local-fields\", fields);\n window.parent.postMessage(message, \"*\");\n }\n },\n takeoverUndoManager(file: DrawioFile) {\n if (currentCleanup) {\n currentCleanup();\n }\n\n const editor = file.getUi().editor;\n const originUndoManager = editor.undoManager;\n\n // bindUndoManager 已安装:不替换 editor.undoManager,只委托 undo/redo\n if (originUndoManager && \"_y\" in originUndoManager) {\n const mxLike = originUndoManager as MxLike;\n const origUndo = mxLike.undo.bind(mxLike);\n const origRedo = mxLike.redo.bind(mxLike);\n const origCanUndo = mxLike.canUndo.bind(mxLike);\n const origCanRedo = mxLike.canRedo.bind(mxLike);\n currentMxLike = mxLike;\n mxLike.undo = () => {\n if (!applyingParentUpdate) {\n window.parent.postMessage({ type: \"undo\" }, \"*\");\n } else {\n origUndo();\n }\n };\n mxLike.redo = () => {\n if (!applyingParentUpdate) {\n window.parent.postMessage({ type: \"redo\" }, \"*\");\n } else {\n origRedo();\n }\n };\n mxLike.canUndo = () => mxLike.indexOfNextAdd > 0;\n mxLike.canRedo = () => mxLike.indexOfNextAdd < mxLike.history.length;\n if (pendingUndoState) {\n syncUndoStateFromServer(mxLike, pendingUndoState);\n pendingUndoState = null;\n }\n window.parent.postMessage({ type: \"request-undo-state\" }, \"*\");\n const cleanup = () => {\n mxLike.undo = origUndo;\n mxLike.redo = origRedo;\n mxLike.canUndo = origCanUndo;\n mxLike.canRedo = origCanRedo;\n currentMxLike = null;\n pendingUndoState = null;\n };\n currentCleanup = cleanup;\n return cleanup;\n }\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: MxLike = {\n eventListeners: [] as Array<string | ListenerFn>,\n history: [] as unknown[],\n indexOfNextAdd: 0,\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 \"\");\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(\n \"[iframe-bridge] undoManager event listener error:\",\n e,\n );\n }\n }\n }\n },\n\n canUndo(): boolean {\n return this.indexOfNextAdd > 0;\n },\n\n canRedo(): boolean {\n return this.indexOfNextAdd < this.history.length;\n },\n\n undo() {\n if (!applyingParentUpdate) {\n window.parent.postMessage({ type: \"undo\" }, \"*\");\n }\n },\n\n redo() {\n if (!applyingParentUpdate) {\n window.parent.postMessage({ type: \"redo\" }, \"*\");\n }\n },\n\n undoableEditHappened() {\n // no-op\n },\n };\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 currentMxLike = mxLike;\n editor.undoManager = mxLike as unknown as DrawioEditor[\"undoManager\"];\n editor.undoListener = function () {};\n\n if (pendingUndoState) {\n syncUndoStateFromServer(mxLike, pendingUndoState);\n pendingUndoState = null;\n }\n window.parent.postMessage({ type: \"request-undo-state\" }, \"*\");\n\n const cleanup = () => {\n editor.undoManager = originUndoManager;\n editor.undoListener = originUndoManager?.undoListener as\n | ((...args: unknown[]) => void)\n | undefined;\n currentMxLike = null;\n pendingUndoState = null;\n };\n\n currentCleanup = cleanup;\n return cleanup;\n },\n destroy: () => {\n while (pendingYdocUpdates.length > 0) {\n const { update, isBaseline } = pendingYdocUpdates.shift()!;\n window.parent.postMessage({ type: \"ydoc-update\", payload: Array.from(update), isBaseline }, \"*\");\n }\n unackedYdocUpdates.clear();\n ydoc.off(\"update\", onYdocUpdate);\n if (useExternalAwareness) {\n (awareness as Awareness).off(\"update\", onAwarenessUpdate);\n }\n window.removeEventListener(\"message\", onMessage);\n if (initRetryTimer) {\n clearInterval(initRetryTimer);\n initRetryTimer = null;\n }\n connectListeners.clear();\n disconnectListeners.clear();\n if (currentCleanup) {\n currentCleanup();\n }\n },\n };\n}\n"],"names":["awareness","localClientId","Y","applyAwarenessUpdate","mxLike","cleanup"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAM,2BAA2B,oBAAI,IAAI,CAAC,UAAU,WAAW,CAAC;AAEhE,SAAS,uBAAuB,KAAsB;AACpD,SAAO,yBAAyB,IAAI,GAAG;AACzC;AAEA,SAAS,8BACP,MACA,MACwC;AACxC,QAAM,2BAAW,IAAI;AAAA,IACnB,GAAG,OAAO,KAAK,QAAA,OAAA,OAAQ,CAAA,CAAE;AAAA,IACzB,GAAG,OAAO,KAAK,QAAA,OAAA,OAAQ,CAAA,CAAE;AAAA,EAAA,CAC1B;AACD,QAAM,UAAkD,CAAA;AACxD,aAAW,OAAO,MAAM;AACtB,UAAM,YAAY,QAAA,OAAA,SAAA,KAAO,GAAA;AACzB,UAAM,YAAY,QAAA,OAAA,SAAA,KAAO,GAAA;AACzB,QAAI,KAAK,UAAU,SAAS,MAAM,KAAK,UAAU,SAAS,GAAG;AAC3D,cAAQ,KAAK,EAAE,KAAK,OAAO,WAAW;AAAA,IACxC;AAAA,EACF;AACA,SAAO;AACT;AAmBA,SAAS,oBAAoB,MAAc,OAAiC;AAC1E,QAAM,SAAS,SAAS,CAAA;AACxB,SAAO;AAAA,IACL;AAAA,IACA,SAAS,MAAM;AAAA,IACf,aAAa,CAAC,MAAc,OAAO,CAAC;AAAA,EAAA;AAExC;AA4CA,SAAS,YAAY,MAAkB,KAA+B;AACpE,MAAI,SAAS;AACb,MAAI,QAAQ;AACZ,MAAI;AACJ,KAAG;AACD,WAAO,KAAK,KAAK;AACjB,eAAW,OAAO,QAAS;AAC3B,aAAS;AAAA,EACX,SAAS,QAAQ;AACjB,SAAO,CAAC,WAAW,GAAG,GAAG;AAC3B;AAEA,SAAS,aAAa,OAAyB;AAC7C,QAAM,QAAkB,CAAA;AACxB,SAAO,QAAQ,KAAM;AACnB,UAAM,KAAM,QAAQ,MAAQ,GAAI;AAChC,eAAW;AAAA,EACb;AACA,QAAM,KAAK,KAAK;AAChB,SAAO;AACT;AAEA,SAAS,cAAc,MAAkB,KAA+B;AACtE,QAAM,CAAC,KAAK,IAAI,IAAI,YAAY,MAAM,GAAG;AACzC,QAAM,MAAM,IAAI,YAAA,EAAc,OAAO,KAAK,SAAS,MAAM,OAAO,GAAG,CAAC;AACpE,SAAO,CAAC,KAAK,OAAO,GAAG;AACzB;AAEA,SAAS,eAAe,KAAuB;AAC7C,QAAM,UAAU,IAAI,cAAc,OAAO,GAAG;AAC5C,SAAO,CAAC,GAAG,aAAa,QAAQ,MAAM,GAAG,GAAG,OAAO;AACrD;AAEA,SAAS,sBACP,QACA,QACA,MACY;AACZ,QAAM,UAAqE,CAAA;AAC3E,QAAM,oCAAoB,IAAA;AAC1B,MAAI,MAAM;AAEV,QAAM,CAAC,OAAO,IAAI,IAAI,YAAY,QAAQ,GAAG;AAC7C,QAAM;AAEN,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,CAAC,UAAU,IAAI,IAAI,YAAY,QAAQ,GAAG;AAChD,UAAM;AACN,UAAM,CAAC,OAAO,IAAI,IAAI,YAAY,QAAQ,GAAG;AAC7C,UAAM;AACN,UAAM,CAAC,OAAO,IAAI,IAAI,cAAc,QAAQ,GAAG;AAC/C,UAAM;AAEN,UAAM,WAAW,aAAa,SAAS,OAAO;AAC9C,QAAI,cAAc,IAAI,QAAQ,GAAG;AAC/B;AAAA,IACF;AAEA,kBAAc,IAAI,QAAQ;AAC1B,YAAQ,KAAK,EAAE,UAAU,UAAU,OAAO,OAAO;AAAA,EACnD;AAEA,QAAM,SAAmB,CAAA;AACzB,SAAO,KAAK,GAAG,aAAa,QAAQ,MAAM,CAAC;AAC3C,aAAW,SAAS,SAAS;AAC3B,WAAO,KAAK,GAAG,aAAa,MAAM,QAAQ,CAAC;AAC3C,WAAO,KAAK,GAAG,aAAa,MAAM,KAAK,CAAC;AACxC,WAAO,KAAK,GAAG,eAAe,MAAM,KAAK,CAAC;AAAA,EAC5C;AAEA,SAAO,IAAI,WAAW,MAAM;AAC9B;AAEA,SAAS,sBAAsB,MAAwD;AACrF,QAAM,6BAAa,IAAA;AACnB,MAAI,MAAM;AACV,QAAM,CAAC,OAAO,IAAI,IAAI,YAAY,MAAM,GAAG;AAC3C,QAAM;AAEN,WAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,UAAM,CAAC,UAAU,IAAI,IAAI,YAAY,MAAM,GAAG;AAC9C,UAAM;AACN,UAAM,CAAA,EAAG,IAAI,IAAI,YAAY,MAAM,GAAG;AACtC,UAAM;AACN,UAAM,CAAC,UAAU,IAAI,IAAI,cAAc,MAAM,GAAG;AAChD,UAAM;AAEN,QAAI,UAAU;AACZ,UAAI;AACF,eAAO,IAAI,UAAU,KAAK,MAAM,QAAQ,CAAC;AAAA,MAC3C,SAAQ,GAAA;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEO,SAAS,2BACd,MACA,SACsB;AACtB,QAAM,EAAE,WAAW,mBAAmB,QAAQ,MAAA,IAAU,4BAAW,CAAA;AACnE,MAAI,uBAAuB;AAC3B,MAAI,iBAAgC;AACpC,MAAI,iBAAsC;AAC1C,MAAI,gBAA+B;AACnC,MAAI,mBAGO;AACX,MAAI,YAAY;AAChB,MAAI,gBAAgB;AACpB,QAAM,iBAAiB;AACvB,QAAM,qBAAuE,CAAA;AAC7E,MAAI,MAAM;AACV,QAAM,yCAAyB,IAAA;AAC/B,MAAI,iBAAwD;AAG5D,MAAI,oBAAoB;AACxB,MAAI,aAAa;AACjB,QAAM,uCAAuB,IAAA;AAC7B,QAAM,0CAA0B,IAAA;AAChC,MAAI,6BAA6D;AAEjE,QAAM,MAAM,QACR,IAAI,SAAoB,QAAQ,IAAI,4BAA4B,GAAG,IAAI,IACvE,MAAM;AAEV,QAAM,uBAAuB,CAAC,CAAC;AAC/B,MAAIA;AACJ,QAAM,kCAAkB,IAAA;AACxB,QAAM,gBAAgB,KAAK,MAAM,KAAK,OAAA,IAAW,UAAU,IAAI;AAC/D,QAAM,qCAAqB,IAAA;AAE3B,WAAS,sBAAqC;AAC5C,aAAS,uBAAuB;AAC9B,aAAO,kBAAA,OAAA,iBAAkB;AAAA,IAC3B;AAEA,WAAO;AAAA,MACL,IAAI,WAAW;AACb,eAAO,qBAAA;AAAA,MACT;AAAA,MACA,IAAI,SAAS;AACX,eAAO;AAAA,MACT;AAAA,MACA,YAAY;AACV,eAAO,IAAI,IAAI,WAAW;AAAA,MAC5B;AAAA,MACA,gBAAgB;AAzPtB,YAAA;AA0PQ,gBAAO,KAAA,YAAY,IAAI,qBAAA,CAAsB,MAAtC,OAAA,KAA2C;AAAA,MACpD;AAAA,MACA,cAAc,OAAuC;AACnD,cAAM,KAAK,qBAAA;AACX,YAAI,UAAU,MAAM;AAClB,sBAAY,OAAO,EAAE;AACrB,gBAAM,SAAS,EAAE,OAAO,CAAA,GAAI,SAAS,IAAI,SAAS,CAAC,EAAE,EAAA;AACrD,yBAAe,QAAQ,CAAA,YAAW,QAAQ,MAAM,CAAC;AAAA,QACnD,OAAO;AACL,gBAAM,UAAU,YAAY,IAAI,EAAE;AAClC,sBAAY,IAAI,IAAI,KAAK;AACzB,gBAAM,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,IAAI,CAAA,GAAI,SAAS,CAAC,EAAE,GAAG,SAAS,CAAA,EAAC;AACvE,yBAAe,QAAQ,CAAA,YAAW,QAAQ,MAAM,CAAC;AAAA,QACnD;AAAA,MACF;AAAA,MACA,mBAAmB,OAAe,OAAgB;AAChD,cAAM,KAAK,qBAAA;AACX,cAAM,UAAU,YAAY,IAAI,EAAE,KAAK,CAAA;AACvC,cAAM,WAAW,cAAA,eAAA,CAAA,GAAK,OAAA,GAAL,EAAc,CAAC,KAAK,GAAG,OAAM;AAC9C,oBAAY,IAAI,IAAI,QAAQ;AAC5B,kCAA0B,OAAO,KAAK;AACtC,cAAM,SAAS,EAAE,OAAO,CAAA,GAAI,SAAS,CAAC,EAAE,GAAG,SAAS,GAAC;AACrD,uBAAe,QAAQ,CAAA,YAAW,QAAQ,MAAM,CAAC;AAAA,MACnD;AAAA,MACA,GAAG,OAAiB,SAAsF;AACxG,YAAI,UAAU,UAAU;AACtB,yBAAe,IAAI,OAAO;AAAA,QAC5B;AAAA,MACF;AAAA,MACA,IAAI,OAAiB,SAAsF;AACzG,YAAI,UAAU,UAAU;AACtB,yBAAe,OAAO,OAAO;AAAA,QAC/B;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AAEA,MAAI,mBAAmB;AACrBA,kBAAY;AAAA,EACd,OAAO;AACLA,kBAAY,oBAAA;AAAA,EACd;AAEA,WAAS,cAAc,SAAkB;AACvC,QAAI,mBAAmB,YAAY;AACjC,aAAO,EAAE,OAAO,QAAQ,WAAA;AAAA,IAC1B;AACA,QAAI,MAAM,QAAQ,OAAO,KAAK,QAAQ,MAAM,CAAC,SAAS,OAAO,SAAS,QAAQ,GAAG;AAC/E,aAAO,EAAE,OAAO,QAAQ,OAAA;AAAA,IAC1B;AACA,WAAO;AAAA,EACT;AAEA,WAAS,WAAW,WAA4B,MAAc,SAAmB;AAC/E,QAAI,CAAC,MAAO;AACZ,QAAI,WAAW,MAAM,cAAc,OAAO,CAAC;AAAA,EAC7C;AAEA,WAAS,8BAA8B;AACrC,UAAM,QAAQA,YAAU,cAAA;AACxB,iCAA6B,QAAQ,mBAAK,KAAA,IAAU;AAAA,EACtD;AAEA,WAAS,0BAA0B,KAAa,OAAgB;AAC9D,QAAI,CAAC,aAAa,CAAC,uBAAuB,GAAG,EAAG;AAChD,UAAM,UAAU,EAAE,MAAM,mBAAmB,KAAK,MAAA;AAChD,eAAW,QAAQ,mBAAmB,OAAO;AAC7C,WAAO,OAAO,YAAY,SAAS,GAAG;AAAA,EACxC;AAEA,WAAS,kBAAkB,SAAkB;AAhU/C,QAAA;AAiUI,eAAW,SAAS,KAAA,QAA8B,SAA9B,OAAA,KAAsC,eAAe,OAAO;AAChF,WAAO,OAAO,YAAY,SAAS,GAAG;AAAA,EACxC;AAEA,WAAS,aAAa,OAAgB;AACpC,QAAI,cAAc,MAAO;AACzB,gBAAY;AACZ,QAAI,OAAO;AACT,sBAAgB;AAChB,kCAAA;AACA,aAAO,mBAAmB,SAAS,GAAG;AACpC,cAAM,EAAE,QAAQ,eAAe,mBAAmB,MAAA;AAClD,YAAI,YAAY;AACd,gBAAM,UAAU,EAAE,MAAM,eAAe,SAAS,MAAM,KAAK,MAAM,GAAG,WAAA;AACpE,iBAAO,OAAO,YAAY,SAAS,GAAG;AAAA,QACxC,OAAO;AACL,gBAAM,SAAS,EAAE;AACjB,gBAAM,UAAU,EAAE,MAAM,eAAe,SAAS,MAAM,KAAK,MAAM,GAAG,YAAY,KAAK,OAAA;AACrF,iBAAO,OAAO,YAAY,SAAS,GAAG;AACtC,6BAAmB,IAAI,QAAQ,EAAE,QAAQ,YAAY;AAAA,QACvD;AAAA,MACF;AACA,UAAI,CAAC,YAAY;AACf,mBAAW,CAAC,UAAU,EAAE,QAAQ,WAAA,CAAY,KAAK,oBAAoB;AACnE,gBAAM,UAAU,EAAE,MAAM,eAAe,SAAS,MAAM,KAAK,MAAM,GAAG,YAAY,KAAK,SAAA;AACrF,iBAAO,OAAO,YAAY,SAAS,GAAG;AAAA,QACxC;AAAA,MACF;AACA,uBAAiB,QAAQ,CAAC,OAAO,GAAA,CAAI;AAAA,IACvC,OAAO;AACL,mCAA6B;AAC7B,UAAI,CAAC,YAAY;AACf,2BAAmB,MAAA;AAAA,MACrB;AACA,0BAAoB,QAAQ,CAAC,OAAO,GAAA,CAAI;AAAA,IAC1C;AAAA,EACF;AAEA,WAAS,iBAAiB;AACxB,QAAI,gBAAgB;AAClB,oBAAc,cAAc;AAAA,IAC9B;AACA,QAAI,CAAC,iBAAiB,mBAAmB,SAAS,GAAG;AACnD,UAAI,CAAC,YAAY;AACf,cAAM,UAAU,mBAAmB,OAAO,CAAC;AAC3C,0BAAkB;AAAA,UAChB,MAAM;AAAA,UACN,SAAS,QAAQ,IAAI,CAAA,OAAM,EAAE,QAAQ,MAAM,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,aAAa;AAAA,QAAA,CACvF;AAAA,MACH,OAAO;AACL,mBAAW,EAAE,QAAQ,WAAA,KAAgB,oBAAoB;AACvD,4BAAkB,EAAE,MAAM,eAAe,SAAS,MAAM,KAAK,MAAM,GAAG,YAAY;AAAA,QACpF;AACA,2BAAmB,SAAS;AAAA,MAC9B;AAAA,IACF;AACA,sBAAkB,EAAE,MAAM,QAAQ;AAClC,qBAAiB,YAAY,MAAM;AACjC,UAAI,CAAC,WAAW;AACd,0BAAkB,EAAE,MAAM,QAAQ;AAAA,MACpC;AAAA,IACF,GAAG,GAAI;AAAA,EACT;AAEA,QAAM,eAAe,CAAC,QAAoB,WAAoB;AAC5D,QAAI,qBAAsB;AAE1B,UAAM,aAAa,WAAW,QAAQ,WAAW;AACjD,QAAI,CAAC,WAAW;AACd,UAAI,mBAAmB,UAAU,gBAAgB;AAC/C,wBAAgB;AAChB,2BAAmB,SAAS;AAC5B,gBAAQ,KAAK,4DAA4D;AAAA,MAC3E;AACA,yBAAmB,KAAK,EAAE,QAAQ,WAAA,CAAY;AAC9C;AAAA,IACF;AACA,QAAI,YAAY;AACd,YAAM,UAAU,EAAE,MAAM,eAAe,SAAS,MAAM,KAAK,MAAM,GAAG,WAAA;AACpE,iBAAW,QAAQ,eAAe,OAAO;AACzC,aAAO,OAAO,YAAY,SAAS,GAAG;AAAA,IACxC,OAAO;AACL,YAAM,SAAS,EAAE;AACjB,YAAM,UAAU,EAAE,MAAM,eAAe,SAAS,MAAM,KAAK,MAAM,GAAG,YAAY,KAAK,OAAA;AACrF,iBAAW,QAAQ,eAAe,OAAO;AACzC,aAAO,OAAO,YAAY,SAAS,GAAG;AACtC,yBAAmB,IAAI,QAAQ,EAAE,QAAQ,YAAY;AAAA,IACvD;AAAA,EACF;AAEA,QAAM,oBAAoB,CAAC;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,EAAA,MAKI;AACJ,QAAI,sBAAsB;AACxB;AAAA,IACF;AACA,QAAI,CAAC,WAAW;AACd;AAAA,IACF;AACA,UAAM,UAAU,CAAC,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO;AACjD,QAAI,QAAQ,WAAW,EAAG;AAE1B,UAAMC,iBAAgBD,YAAU;AAChC,UAAM,eAAe,QAAQ,SAASC,cAAa;AACnD,QAAI,CAAC,aAAc;AAEnB,UAAM,YAAYD,YAAU,cAAA;AAC5B,UAAM,eAAe;AAAA,MACnB;AAAA,MACA;AAAA,IAAA;AAEF,iCAA6B,YAAY,mBAAK,SAAA,IAAc;AAC5D,eAAW,EAAE,KAAK,MAAA,KAAW,cAAc;AACzC,gCAA0B,KAAK,KAAK;AAAA,IACtC;AAAA,EACF;AAEA,QAAM,0BAA0B,CAC9B,QACA,SACG;AACH,UAAM,EAAE,eAAe,cAAA,IAAkB;AACzC,UAAM,WAAW,OAAO;AACxB,UAAM,WAAW,iBAAiB;AAClC,UAAM,YAAY,iBAAiB,MAAM,iBAAiB;AAC1D,2BAAuB;AACvB,WAAO,UAAU,IAAI,MAAM,QAAQ,EAAE,KAAK,EAAE;AAC5C,WAAO,iBAAiB;AACxB,QAAI,aAAa,GAAG;AAClB,aAAO,UAAU,oBAAoB,OAAO,CAAC;AAAA,IAC/C,WAAW,WAAW,UAAU;AAC9B,aAAO;AAAA,QACL,oBAAoB,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAA,EAAC,EAAE,CAAG;AAAA,MAAA;AAAA,IAEzD,WAAW,WAAW,UAAU;AAC9B,aAAO;AAAA,QACL,oBAAoB,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAA,EAAC,EAAE,CAAG;AAAA,MAAA;AAAA,IAEzD,OAAO;AACL,aAAO;AAAA,QACL,oBAAoB,OAAO,EAAE,MAAM,EAAE,SAAS,CAAA,EAAC,EAAE,CAAG;AAAA,MAAA;AAAA,IAExD;AACA,2BAAuB;AAAA,EACzB;AAEA,QAAM,YAAY,CAAC,UAAwB;AACzC,QAAI,MAAM,WAAW,OAAO,OAAQ;AACpC,QAAI,CAAC,MAAM,QAAQ,OAAO,MAAM,SAAS,SAAU;AACnD,UAAM,EAAE,MAAM,SAAS,gBAAgB,iBAAA,IAAqB,MAAM;AAElE,eAAW,QAAQ,MAAM,OAAO;AAChC,QAAI,SAAS,UAAU,oBAAoB,MAAM;AAC/C,uBAAiB;AAEjB,UAAI,MAAM,KAAK,mBAAmB,GAAG;AACnC,4BAAoB;AACpB,YAAI,YAAY;AAEd,uBAAa;AACb,cAAI,oCAAoC,MAAM,KAAK,kBAAkB,0BAA0B;AAAA,QACjG,OAAO;AACL,cAAI,oCAAoC,MAAM,KAAK,kBAAkB,GAAG;AAAA,QAC1E;AAAA,MACF,WAAW,CAAC,mBAAmB;AAC7B,qBAAa;AACb,2BAAmB,MAAA;AACnB,YAAI,qDAAqD;AAAA,MAC3D;AACA;AAAA,IACF;AACA,QAAI,SAAS,mBAAmB;AAC9B,YAAM,SAAS,MAAM,KAAK;AAC1B,UAAI,UAAU,MAAM;AAClB,2BAAmB,OAAO,MAAM;AAAA,MAClC;AACA;AAAA,IACF;AAEA,QAAI,SAAS,eAAe,SAAS,eAAe;AAClD,6BAAuB;AACvBE,mBAAE,YAAY,MAAM,IAAI,WAAW,OAAO,CAAC;AAC3C,6BAAuB;AAEvB,UAAI,SAAS,eAAe,MAAM,KAAK,mBAAmB,MAAM;AAC9D,YAAI,MAAM,KAAK,mBAAmB,KAAK,CAAC,mBAAmB;AACzD,8BAAoB;AACpB,cAAI,oCAAoC,MAAM,KAAK,kBAAkB,kBAAkB;AAAA,QACzF;AAAA,MACF,WAAW,SAAS,eAAe,CAAC,qBAAqB,CAAC,YAAY;AAGpE,qBAAa;AACb,2BAAmB,MAAA;AACnB,YAAI,yDAAyD;AAAA,MAC/D;AACA,UAAI,SAAS,eAAe,CAAC,WAAW;AACtC,qBAAa,IAAI;AACjB,YAAI,gBAAgB;AAClB,wBAAc,cAAc;AAC5B,2BAAiB;AAAA,QACnB;AAAA,MACF;AAAA,IACF,WAAW,SAAS,oBAAoB,SAAS,oBAAoB;AACnE,iBAAW,QAAQ,MAAM,OAAO;AAChC,YAAM,cAAc;AACpB,UAAI,oBAAoB,MAAM;AAC5B,yBAAiB;AACjB,YAAI,yBAAyB,SAAS,oBAAoB,QAAQ,gBAAgB,kBAAkB;AAClG,gBAAM,YAAY,YAAY,IAAI,WAAW;AAC7C,cAAI,WAAW;AACb,wBAAY,OAAO,WAAW;AAC9B,wBAAY,IAAI,kBAAkB,SAAS;AAAA,UAC7C;AAAA,QACF;AAAA,MACF;AAEA,UAAI,sBAAsB;AACxB,cAAM,WAAW,oBAAA,OAAA,mBAAoB;AACrC,cAAM,UAAUF,YAAU;AAE1B,+BAAuB;AACvB,YAAI,YAAY,QAAQ,aAAa,SAAS;AAC5C,gBAAM,WAAW;AAAA,YACf,IAAI,WAAW,OAAO;AAAA,YACtB;AAAA,YACA;AAAA,UAAA;AAGF,cAAI,SAAS,kBAAkB;AAC5BA,wBAAwB,KAAK,OAAO,OAAO;AAC5CA,wBAAU,cAAc,IAAI;AAAA,UAC9B;AAEAG,yCAAqBH,aAAwB,UAAU,IAAI;AAAA,QAC7D,OAAO;AACLG,oBAAAA,qBAAqBH,aAAwB,IAAI,WAAW,OAAO,GAAG,IAAI;AAAA,QAC5E;AACA,+BAAuB;AAAA,MACzB,OAAO;AACL,cAAM,eAAe,sBAAsB,IAAI,WAAW,OAAO,CAAC;AAClE,+BAAuB;AACvB,cAAM,mBAA6B,CAAA;AACnC,cAAM,mBAA6B,CAAA;AACnC,mBAAW,CAAC,IAAI,KAAK,KAAK,cAAc;AACtC,gBAAM,UAAU,YAAY,IAAI,EAAE;AAClC,gBAAM,UAAU,CAAC,WAAW,KAAK,UAAU,YAAY,IAAI,EAAE,CAAC,MAAM,KAAK,UAAU,KAAK;AACxF,sBAAY,IAAI,IAAI,KAAK;AACzB,cAAI,SAAS;AACX,6BAAiB,KAAK,EAAE;AAAA,UAC1B;AAAA,QACF;AACA,mBAAW,CAAC,EAAE,KAAK,aAAa;AAC9B,cAAI,CAAC,aAAa,IAAI,EAAE,GAAG;AACzB,wBAAY,OAAO,EAAE;AACrB,6BAAiB,KAAK,EAAE;AAAA,UAC1B;AAAA,QACF;AACA,YAAI,iBAAiB,SAAS,KAAK,iBAAiB,SAAS,GAAG;AAC9D,gBAAM,SAAS,EAAE,OAAO,CAAA,GAAI,SAAS,kBAAkB,SAAS,iBAAA;AAChE,yBAAe,QAAQ,CAAA,YAAW,QAAQ,MAAM,CAAC;AAAA,QACnD;AACA,+BAAuB;AAAA,MACzB;AAAA,IACF,WAAW,SAAS,cAAc;AAChC,UAAI,CAAC,eAAe;AAClB,2BAAmB,MAAM;AAAA,MAC3B,OAAO;AACL,gCAAwB,eAAe,MAAM,IAAI;AAAA,MACnD;AAAA,IACF,WAAW,SAAS,cAAc;AAChC,mBAAa,KAAK;AAClB,qBAAA;AAAA,IACF;AAAA,EACF;AAEA,OAAK,GAAG,UAAU,YAAY;AAG9B,MAAI,sBAAsB;AACvBA,gBAAwB,GAAG,UAAU,iBAAiB;AAAA,EACzD;AACA,SAAO,iBAAiB,WAAW,SAAS;AAE5C,iBAAA;AAGA,aAAW,MAAM;AACf,WAAO,OAAO,YAAY,EAAE,MAAM,OAAA,GAAU,GAAG;AAAA,EACjD,GAAG,GAAG;AAEN,SAAO;AAAA,IACL,IAAI,iBAAiB;AACnB,aAAO;AAAA,IACT;AAAA,IACA,IAAI,YAAY;AACd,aAAO;AAAA,IACT;AAAA,IACA,IAAI,YAAY;AACd,aAAOA;AAAAA,IACT;AAAA,IACA,UAAU,IAAgB;AACxB,uBAAiB,IAAI,EAAE;AACvB,aAAO,MAAM,iBAAiB,OAAO,EAAE;AAAA,IACzC;AAAA,IACA,aAAa,IAAgB;AAC3B,0BAAoB,IAAI,EAAE;AAC1B,aAAO,MAAM,oBAAoB,OAAO,EAAE;AAAA,IAC5C;AAAA,IACA,GAAG,OAAiC,IAAgB;AAClD,UAAI,UAAU,WAAW;AACvB,yBAAiB,IAAI,EAAE;AACvB,eAAO,MAAM,iBAAiB,OAAO,EAAE;AAAA,MACzC,OAAO;AACL,4BAAoB,IAAI,EAAE;AAC1B,eAAO,MAAM,oBAAoB,OAAO,EAAE;AAAA,MAC5C;AAAA,IACF;AAAA,IACA,eAAe,QAAiC;AAC9C,YAAM,eAAeA,YAAU,cAAA,KAAmB,CAAA;AAClD,YAAM,cAAe,aAAoD,QAAQ,CAAA;AACjF,YAAM,UAAU,kCAAK,WAAA,GAAgB,MAAA;AACrCA,kBAAU,cAAc,iCACnB,YAAA,GADmB;AAAA,QAEtB,MAAM;AAAA,MAAA,CACR,CAAC;AAED,UAAI,WAAW;AACb,cAAM,UAAU,EAAE,MAAM,oBAAoB,OAAA;AAC5C,mBAAW,QAAQ,oBAAoB,MAAM;AAC7C,eAAO,OAAO,YAAY,SAAS,GAAG;AAAA,MACxC;AAAA,IACF;AAAA,IACA,oBAAoB,MAAkB;AACpC,UAAI,gBAAgB;AAClB,uBAAA;AAAA,MACF;AAEA,YAAM,SAAS,KAAK,MAAA,EAAQ;AAC5B,YAAM,oBAAoB,OAAO;AAGjC,UAAI,qBAAqB,QAAQ,mBAAmB;AAClD,cAAMI,UAAS;AACf,cAAM,WAAWA,QAAO,KAAK,KAAKA,OAAM;AACxC,cAAM,WAAWA,QAAO,KAAK,KAAKA,OAAM;AACxC,cAAM,cAAcA,QAAO,QAAQ,KAAKA,OAAM;AAC9C,cAAM,cAAcA,QAAO,QAAQ,KAAKA,OAAM;AAC9C,wBAAgBA;AAChBA,gBAAO,OAAO,MAAM;AAClB,cAAI,CAAC,sBAAsB;AACzB,mBAAO,OAAO,YAAY,EAAE,MAAM,OAAA,GAAU,GAAG;AAAA,UACjD,OAAO;AACL,qBAAA;AAAA,UACF;AAAA,QACF;AACAA,gBAAO,OAAO,MAAM;AAClB,cAAI,CAAC,sBAAsB;AACzB,mBAAO,OAAO,YAAY,EAAE,MAAM,OAAA,GAAU,GAAG;AAAA,UACjD,OAAO;AACL,qBAAA;AAAA,UACF;AAAA,QACF;AACAA,gBAAO,UAAU,MAAMA,QAAO,iBAAiB;AAC/CA,gBAAO,UAAU,MAAMA,QAAO,iBAAiBA,QAAO,QAAQ;AAC9D,YAAI,kBAAkB;AACpB,kCAAwBA,SAAQ,gBAAgB;AAChD,6BAAmB;AAAA,QACrB;AACA,eAAO,OAAO,YAAY,EAAE,MAAM,qBAAA,GAAwB,GAAG;AAC7D,cAAMC,WAAU,MAAM;AACpBD,kBAAO,OAAO;AACdA,kBAAO,OAAO;AACdA,kBAAO,UAAU;AACjBA,kBAAO,UAAU;AACjB,0BAAgB;AAChB,6BAAmB;AAAA,QACrB;AACA,yBAAiBC;AACjB,eAAOA;AAAAA,MACT;AAEA,YAAM,QAAqC,CAAA;AAC3C,YAAM,MAAM,MAAM,QAAQ,qBAAA,OAAA,SAAA,kBAAmB,cAAc,IACtD,kBAAkB,iBACnB,CAAA;AACJ,eAAS,IAAI,GAAG,IAAI,IAAI,IAAI,QAAQ,KAAK,GAAG;AAC1C,cAAM,MAAM,OAAO,IAAI,CAAC,CAAC;AACzB,cAAM,KAAK,IAAI,IAAI,CAAC;AACpB,cAAM,KAAK,CAAC,KAAK,EAAE,CAAC;AAAA,MACtB;AAEA,YAAM,SAAiB;AAAA,QACrB,gBAAgB,CAAA;AAAA,QAChB,SAAS,CAAA;AAAA,QACT,gBAAgB;AAAA,QAEhB,YAAY,MAAc,IAAgB;AACxC,eAAK,eAAe,KAAK,MAAM,EAAE;AAAA,QACnC;AAAA,QAEA,UAAU,KAAc;AAxtBhC,cAAA,IAAA;AAytBU,gBAAM,aACH,OAAA,OAAA,SAAA,IAAuC,WACtC,MAAA,KAAA,OAAA,OAAA,SAAA,IAAgD,YAAhD,OAAA,SAAA,GAAA,KAAA,GAAA,MAAA,OAAA,KACA;AACJ,mBAAS,IAAI,GAAG,IAAI,IAAI,KAAK,eAAe,QAAQ,KAAK,GAAG;AAC1D,kBAAM,MAAM,KAAK,eAAe,CAAC;AACjC,kBAAM,WAAW,KAAK,eAAe,IAAI,CAAC;AAC1C,gBAAI,QAAQ,WAAW;AACrB,kBAAI;AACF,yBAAS,MAAM,GAAG;AAAA,cACpB,SAAS,GAAG;AACV,wBAAQ;AAAA,kBACN;AAAA,kBACA;AAAA,gBAAA;AAAA,cAEJ;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QAEA,UAAmB;AACjB,iBAAO,KAAK,iBAAiB;AAAA,QAC/B;AAAA,QAEA,UAAmB;AACjB,iBAAO,KAAK,iBAAiB,KAAK,QAAQ;AAAA,QAC5C;AAAA,QAEA,OAAO;AACL,cAAI,CAAC,sBAAsB;AACzB,mBAAO,OAAO,YAAY,EAAE,MAAM,OAAA,GAAU,GAAG;AAAA,UACjD;AAAA,QACF;AAAA,QAEA,OAAO;AACL,cAAI,CAAC,sBAAsB;AACzB,mBAAO,OAAO,YAAY,EAAE,MAAM,OAAA,GAAU,GAAG;AAAA,UACjD;AAAA,QACF;AAAA,QAEA,uBAAuB;AAAA,QAEvB;AAAA,MAAA;AAGF,YAAM,QAAQ,CAAC,CAAC,KAAK,EAAE,MAAM;AAC3B,cAAM,IAAI,IAAI,YAAA;AACd,YAAI,MAAM,SAAS,MAAM,WAAW,MAAM,UAAU,MAAM,QAAQ;AAChE,iBAAO,YAAY,GAAG,EAAE;AAAA,QAC1B;AAAA,MACF,CAAC;AAED,sBAAgB;AAChB,aAAO,cAAc;AACrB,aAAO,eAAe,WAAY;AAAA,MAAC;AAEnC,UAAI,kBAAkB;AACpB,gCAAwB,QAAQ,gBAAgB;AAChD,2BAAmB;AAAA,MACrB;AACA,aAAO,OAAO,YAAY,EAAE,MAAM,qBAAA,GAAwB,GAAG;AAE7D,YAAM,UAAU,MAAM;AACpB,eAAO,cAAc;AACrB,eAAO,eAAe,qBAAA,OAAA,SAAA,kBAAmB;AAGzC,wBAAgB;AAChB,2BAAmB;AAAA,MACrB;AAEA,uBAAiB;AACjB,aAAO;AAAA,IACT;AAAA,IACA,SAAS,MAAM;AACb,aAAO,mBAAmB,SAAS,GAAG;AACpC,cAAM,EAAE,QAAQ,eAAe,mBAAmB,MAAA;AAClD,eAAO,OAAO,YAAY,EAAE,MAAM,eAAe,SAAS,MAAM,KAAK,MAAM,GAAG,WAAA,GAAc,GAAG;AAAA,MACjG;AACA,yBAAmB,MAAA;AACnB,WAAK,IAAI,UAAU,YAAY;AAC/B,UAAI,sBAAsB;AACvBL,oBAAwB,IAAI,UAAU,iBAAiB;AAAA,MAC1D;AACA,aAAO,oBAAoB,WAAW,SAAS;AAC/C,UAAI,gBAAgB;AAClB,sBAAc,cAAc;AAC5B,yBAAiB;AAAA,MACnB;AACA,uBAAiB,MAAA;AACjB,0BAAoB,MAAA;AACpB,UAAI,gBAAgB;AAClB,uBAAA;AAAA,MACF;AAAA,IACF;AAAA,EAAA;AAEJ;;"}
|
|
1
|
+
{"version":3,"file":"provider.cjs","sources":["../../../iframe-bridge/src/provider.ts"],"sourcesContent":["import * as Y from \"yjs\";\nimport {\n Awareness,\n applyAwarenessUpdate,\n} from \"y-protocols/awareness\";\nimport { IFRAME_ORIGIN, BASELINE_ORIGIN } from \"./origin.js\";\nconst IFRAME_BRIDGE_STATE_KEYS = new Set([\"cursor\", \"selection\"]);\n\nfunction isIframeBridgeStateKey(key: string): boolean {\n return IFRAME_BRIDGE_STATE_KEYS.has(key);\n}\n\nfunction getAwarenessStateFieldChanges(\n prev: Record<string, unknown> | null,\n next: Record<string, unknown> | null,\n): Array<{ key: string; value: unknown }> {\n const keys = new Set([\n ...Object.keys(prev ?? {}),\n ...Object.keys(next ?? {}),\n ]);\n const changes: Array<{ key: string; value: unknown }> = [];\n for (const key of keys) {\n const prevValue = prev?.[key];\n const nextValue = next?.[key];\n if (JSON.stringify(prevValue) !== JSON.stringify(nextValue)) {\n changes.push({ key, value: nextValue });\n }\n }\n return changes;\n}\n\n/**\n * Awareness-like 接口,只需要支持本地状态管理。\n * 用于 iframe-bridge provider 不需要与父页面同步 awareness 的场景。\n */\nexport interface AwarenessLike {\n readonly clientID: number;\n readonly states: Map<number, Record<string, unknown>>;\n getStates(): Map<number, Record<string, unknown>>;\n getLocalState(): Record<string, unknown> | null;\n setLocalState(state: Record<string, unknown> | null): void;\n setLocalStateField(field: string, value: unknown): void;\n on(event: \"update\", handler: (update: { added: number[]; updated: number[]; removed: number[] }) => void): void;\n off(event: \"update\", handler: (update: { added: number[]; updated: number[]; removed: number[] }) => void): void;\n}\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\ntype MxLike = Record<string, unknown> & {\n eventListeners: Array<string | ListenerFn>;\n history: unknown[];\n indexOfNextAdd: number;\n addListener(name: string, fn: ListenerFn): void;\n fireEvent(evt: unknown): void;\n canUndo(): boolean;\n canRedo(): boolean;\n undo(): void;\n redo(): void;\n undoableEditHappened(_edit: unknown): void;\n};\n\nexport interface DrawioEditor {\n undoManager?: {\n eventListeners?: unknown[];\n [key: string]: unknown;\n };\n undoListener?: (...args: unknown[]) => void;\n}\n\nexport interface DrawioFile {\n getUi(): { editor: DrawioEditor };\n}\n\nexport interface IframeBridgeProviderOptions {\n awareness?: Awareness;\n debug?: boolean;\n /** 一致性检查间隔(毫秒),0 或不传则禁用。定期比较 state vector,不一致时请求 full sync。 */\n consistencyCheckInterval?: number;\n}\n\nexport interface IframeBridgeProvider {\n serverClientId: number | null;\n connected: boolean;\n awareness: Awareness;\n onConnect: (fn: () => void) => () => void;\n onDisconnect: (fn: () => void) => () => void;\n on: (event: \"connect\" | \"disconnect\", fn: () => void) => () => void;\n setLocalFields: (fields: Record<string, unknown>) => void;\n takeoverUndoManager: (file: DrawioFile) => () => void;\n destroy: () => void;\n}\n\nfunction readVarUint(data: Uint8Array, pos: number): [number, number] {\n let result = 0;\n let shift = 0;\n let byte: number;\n do {\n byte = data[pos++];\n result |= (byte & 0x7f) << shift;\n shift += 7;\n } while (byte >= 0x80);\n return [result >>> 0, pos];\n}\n\nfunction writeVarUint(value: number): number[] {\n const bytes: number[] = [];\n while (value > 0x7f) {\n bytes.push((value & 0x7f) | 0x80);\n value >>>= 7;\n }\n bytes.push(value);\n return bytes;\n}\n\nfunction readVarString(data: Uint8Array, pos: number): [string, number] {\n const [len, pos2] = readVarUint(data, pos);\n const str = new TextDecoder().decode(data.subarray(pos2, pos2 + len));\n return [str, pos2 + len];\n}\n\nfunction writeVarString(str: string): number[] {\n const encoded = new TextEncoder().encode(str);\n return [...writeVarUint(encoded.length), ...encoded];\n}\n\nfunction remapClientIdInUpdate(\n update: Uint8Array,\n fromId: number,\n toId: number,\n): Uint8Array {\n const entries: Array<{ clientID: number; clock: number; state: string }> = [];\n const seenClientIds = new Set<number>();\n let pos = 0;\n\n const [count, pos2] = readVarUint(update, pos);\n pos = pos2;\n\n for (let i = 0; i < count; i++) {\n const [clientID, pos3] = readVarUint(update, pos);\n pos = pos3;\n const [clock, pos4] = readVarUint(update, pos);\n pos = pos4;\n const [state, pos5] = readVarString(update, pos);\n pos = pos5;\n\n const mappedId = clientID === fromId ? toId : clientID;\n if (seenClientIds.has(mappedId)) {\n continue;\n }\n\n seenClientIds.add(mappedId);\n entries.push({ clientID: mappedId, clock, state });\n }\n\n const result: number[] = [];\n result.push(...writeVarUint(entries.length));\n for (const entry of entries) {\n result.push(...writeVarUint(entry.clientID));\n result.push(...writeVarUint(entry.clock));\n result.push(...writeVarString(entry.state));\n }\n\n return new Uint8Array(result);\n}\n\nfunction parseAwarenessPayload(data: Uint8Array): Map<number, Record<string, unknown>> {\n const result = new Map<number, Record<string, unknown>>();\n let pos = 0;\n const [count, pos2] = readVarUint(data, pos);\n pos = pos2;\n\n for (let i = 0; i < count; i++) {\n const [clientID, pos3] = readVarUint(data, pos);\n pos = pos3;\n const [, pos4] = readVarUint(data, pos);\n pos = pos4;\n const [stateStr, pos5] = readVarString(data, pos);\n pos = pos5;\n\n if (stateStr) {\n try {\n result.set(clientID, JSON.parse(stateStr));\n } catch {\n // no-op\n }\n }\n }\n return result;\n}\n\nexport function createIframeBridgeProvider(\n ydoc: Y.Doc,\n options?: IframeBridgeProviderOptions,\n): IframeBridgeProvider {\n const { awareness: externalAwareness, debug = false, consistencyCheckInterval = 0 } = options ?? {};\n let applyingParentUpdate = false;\n let serverClientId: number | null = null;\n let currentCleanup: (() => void) | null = null;\n let currentMxLike: MxLike | null = null;\n let pendingUndoState: {\n undoStackSize?: number;\n redoStackSize?: number;\n } | null = null;\n let connected = false;\n let forceFullSync = false;\n const MAX_QUEUE_SIZE = 1000;\n const pendingYdocUpdates: Array<{update: Uint8Array, isBaseline: boolean}> = [];\n let seq = 0;\n const unackedYdocUpdates = new Map<number, { update: Uint8Array; isBaseline: boolean }>();\n let initRetryTimer: ReturnType<typeof setInterval> | null = null;\n let consistencyTimer: ReturnType<typeof setInterval> | null = null;\n \n // Legacy mode detection: old servers don't send protocolVersion in pong\n let serverSupportsAck = false;\n let legacyMode = false;\n const connectListeners = new Set<() => void>();\n const disconnectListeners = new Set<() => void>();\n let lastLocalAwarenessSnapshot: Record<string, unknown> | null = null;\n\n const log = debug\n ? (...args: unknown[]) => console.log(\"[iframe-bridge provider]\", ...args)\n : () => undefined;\n\n const useExternalAwareness = !!externalAwareness;\n let awareness: Awareness | AwarenessLike;\n const localStates = new Map<number, Record<string, unknown>>();\n const localClientId = Math.floor(Math.random() * 2147483647) + 1;\n const updateHandlers = new Set<(update: { added: number[]; updated: number[]; removed: number[] }) => void>();\n\n function createAwarenessLike(): AwarenessLike {\n function getEffectiveClientId() {\n return serverClientId ?? localClientId;\n }\n\n return {\n get clientID() {\n return getEffectiveClientId();\n },\n get states() {\n return localStates;\n },\n getStates() {\n return new Map(localStates);\n },\n getLocalState() {\n return localStates.get(getEffectiveClientId()) ?? null;\n },\n setLocalState(state: Record<string, unknown> | null) {\n const id = getEffectiveClientId();\n if (state === null) {\n localStates.delete(id);\n const update = { added: [], updated: [], removed: [id] };\n updateHandlers.forEach(handler => handler(update));\n } else {\n const existed = localStates.has(id);\n localStates.set(id, state);\n const update = { added: !existed ? [id] : [], updated: [id], removed: [] };\n updateHandlers.forEach(handler => handler(update));\n }\n },\n setLocalStateField(field: string, value: unknown) {\n const id = getEffectiveClientId();\n const current = localStates.get(id) || {};\n const newState = { ...current, [field]: value };\n localStates.set(id, newState);\n postSetLocalStateToParent(field, value);\n const update = { added: [], updated: [id], removed: [] };\n updateHandlers.forEach(handler => handler(update));\n },\n on(event: \"update\", handler: (update: { added: number[]; updated: number[]; removed: number[] }) => void) {\n if (event === \"update\") {\n updateHandlers.add(handler);\n }\n },\n off(event: \"update\", handler: (update: { added: number[]; updated: number[]; removed: number[] }) => void) {\n if (event === \"update\") {\n updateHandlers.delete(handler);\n }\n },\n };\n }\n\n if (externalAwareness) {\n awareness = externalAwareness;\n } else {\n awareness = createAwarenessLike();\n }\n\n function formatPayload(payload: unknown) {\n if (payload instanceof Uint8Array) {\n return { bytes: payload.byteLength };\n }\n if (Array.isArray(payload) && payload.every((item) => typeof item === \"number\")) {\n return { bytes: payload.length };\n }\n return payload;\n }\n\n function logMessage(direction: \"send\" | \"recv\", type: string, payload?: unknown) {\n if (!debug) return;\n log(direction, type, formatPayload(payload));\n }\n\n function snapshotLocalAwarenessState() {\n const state = awareness.getLocalState();\n lastLocalAwarenessSnapshot = state ? { ...state } : null;\n }\n\n function postSetLocalStateToParent(key: string, value: unknown) {\n if (!connected || !isIframeBridgeStateKey(key)) return;\n const message = { type: \"set-local-state\", key, value };\n logMessage(\"send\", \"set-local-state\", message);\n window.parent.postMessage(message, \"*\");\n }\n\n function parentPostMessage(message: unknown) {\n logMessage(\"send\", (message as { type?: string }).type ?? \"postMessage\", message);\n window.parent.postMessage(message, \"*\");\n }\n\n function setConnected(value: boolean) {\n if (connected === value) return;\n connected = value;\n if (value) {\n forceFullSync = false;\n snapshotLocalAwarenessState();\n while (pendingYdocUpdates.length > 0) {\n const { update, isBaseline } = pendingYdocUpdates.shift()!;\n if (legacyMode) {\n const message = { type: \"ydoc-update\", payload: Array.from(update), isBaseline };\n window.parent.postMessage(message, \"*\");\n } else {\n const seqNum = ++seq;\n const message = { type: \"ydoc-update\", payload: Array.from(update), isBaseline, seq: seqNum };\n window.parent.postMessage(message, \"*\");\n unackedYdocUpdates.set(seqNum, { update, isBaseline });\n }\n }\n if (!legacyMode) {\n for (const [savedSeq, { update, isBaseline }] of unackedYdocUpdates) {\n const message = { type: \"ydoc-update\", payload: Array.from(update), isBaseline, seq: savedSeq };\n window.parent.postMessage(message, \"*\");\n }\n }\n connectListeners.forEach((fn) => fn());\n // 连接后启动一致性检查\n startConsistencyCheck();\n } else {\n lastLocalAwarenessSnapshot = null;\n if (!legacyMode) {\n unackedYdocUpdates.clear();\n }\n disconnectListeners.forEach((fn) => fn());\n }\n }\n\n function startInitRetry() {\n if (initRetryTimer) {\n clearInterval(initRetryTimer);\n }\n if (!forceFullSync && pendingYdocUpdates.length > 0) {\n if (!legacyMode) {\n const updates = pendingYdocUpdates.splice(0);\n parentPostMessage({\n type: \"ydoc-pending-updates\",\n payload: updates.map(u => ({ update: Array.from(u.update), isBaseline: u.isBaseline })),\n });\n } else {\n for (const { update, isBaseline } of pendingYdocUpdates) {\n parentPostMessage({ type: \"ydoc-update\", payload: Array.from(update), isBaseline });\n }\n pendingYdocUpdates.length = 0;\n }\n }\n parentPostMessage({ type: \"init\" });\n initRetryTimer = setInterval(() => {\n if (!connected) {\n parentPostMessage({ type: \"init\" });\n }\n }, 1000);\n }\n\n function startConsistencyCheck() {\n if (consistencyTimer) clearInterval(consistencyTimer);\n if (consistencyCheckInterval <= 0) return;\n consistencyTimer = setInterval(() => {\n if (!connected) return;\n // 发送本地 state vector 给 server 比较\n const sv = Y.encodeStateVector(ydoc);\n parentPostMessage({ type: \"consistency-check\", stateVector: Array.from(sv) });\n log(\"consistency-check sent\");\n }, consistencyCheckInterval);\n }\n\n const onYdocUpdate = (update: Uint8Array, origin: unknown) => {\n if (applyingParentUpdate) return;\n // 检测基线数据:origin 为 null 时是 xml2ydoc 首次初始化\n const isBaseline = origin === null || origin === undefined;\n if (!connected) {\n if (pendingYdocUpdates.length >= MAX_QUEUE_SIZE) {\n forceFullSync = true;\n pendingYdocUpdates.length = 0;\n console.warn(\"[iframe-bridge] queue full, forcing full sync on reconnect\");\n }\n pendingYdocUpdates.push({ update, isBaseline });\n return;\n }\n if (legacyMode) {\n const message = { type: \"ydoc-update\", payload: Array.from(update), isBaseline };\n logMessage(\"send\", \"ydoc-update\", message);\n window.parent.postMessage(message, \"*\");\n } else {\n const seqNum = ++seq;\n const message = { type: \"ydoc-update\", payload: Array.from(update), isBaseline, seq: seqNum };\n logMessage(\"send\", \"ydoc-update\", message);\n window.parent.postMessage(message, \"*\");\n unackedYdocUpdates.set(seqNum, { update, isBaseline });\n }\n };\n\n const onAwarenessUpdate = ({\n added,\n updated,\n removed,\n }: {\n added: number[];\n updated: number[];\n removed: number[];\n }) => {\n if (applyingParentUpdate) {\n return;\n }\n if (!connected) {\n return;\n }\n const changes = [...added, ...updated, ...removed];\n if (changes.length === 0) return;\n\n const localClientId = awareness.clientID;\n const localChanged = changes.includes(localClientId);\n if (!localChanged) return;\n\n const nextState = awareness.getLocalState();\n const fieldChanges = getAwarenessStateFieldChanges(\n lastLocalAwarenessSnapshot,\n nextState,\n );\n lastLocalAwarenessSnapshot = nextState ? { ...nextState } : null;\n for (const { key, value } of fieldChanges) {\n postSetLocalStateToParent(key, value);\n }\n };\n\n const syncUndoStateFromServer = (\n mxLike: MxLike,\n data: { undoStackSize?: number; redoStackSize?: number },\n ) => {\n const { undoStackSize, redoStackSize } = data;\n const oldIndex = mxLike.indexOfNextAdd;\n const newIndex = undoStackSize || 0;\n const newTotal = (undoStackSize || 0) + (redoStackSize || 0);\n applyingParentUpdate = true;\n mxLike.history = new Array(newTotal).fill({});\n mxLike.indexOfNextAdd = newIndex;\n if (newTotal === 0) {\n mxLike.fireEvent(createMxEventObject(\"clear\"));\n } else if (newIndex < oldIndex) {\n mxLike.fireEvent(\n createMxEventObject(\"undo\", { edit: { changes: [] } }),\n );\n } else if (newIndex > oldIndex) {\n mxLike.fireEvent(\n createMxEventObject(\"redo\", { edit: { changes: [] } }),\n );\n } else {\n mxLike.fireEvent(\n createMxEventObject(\"add\", { edit: { changes: [] } }),\n );\n }\n applyingParentUpdate = false;\n };\n\n const onMessage = (event: MessageEvent) => {\n if (event.source !== window.parent) return;\n if (!event.data || typeof event.data !== 'object') return;\n const { type, payload, serverClientId: receivedServerId } = event.data;\n\n logMessage(\"recv\", type, payload);\n if (type === \"pong\" && receivedServerId != null) {\n serverClientId = receivedServerId;\n // 版本号检测:新版 server 在 pong 里带 protocolVersion\n if (event.data.protocolVersion >= 2) {\n serverSupportsAck = true;\n if (legacyMode) {\n // ydoc-sync 先到且无 protocolVersion 时误判了 legacy,纠正回来\n legacyMode = false;\n log(\"server supports ack (protocol v\" + event.data.protocolVersion + \", corrected from legacy)\");\n } else {\n log(\"server supports ack (protocol v\" + event.data.protocolVersion + \")\");\n }\n } else if (!serverSupportsAck) {\n legacyMode = true;\n unackedYdocUpdates.clear();\n log(\"legacy mode detected: server has no protocolVersion\");\n }\n return;\n }\n if (type === \"ydoc-update-ack\") {\n const ackSeq = event.data.seq;\n if (ackSeq != null) {\n unackedYdocUpdates.delete(ackSeq);\n }\n return;\n }\n\n if (type === \"ydoc-sync\" || type === \"ydoc-update\") {\n applyingParentUpdate = true;\n // 使用 origin 区分 baseline vs 编辑数据,server 端 UndoManager 可据此追踪\n const isBaseline = (event.data && typeof event.data === \"object\" && event.data.isBaseline) ? true : false;\n const applyOrigin = isBaseline ? BASELINE_ORIGIN : IFRAME_ORIGIN;\n Y.applyUpdate(ydoc, new Uint8Array(payload), applyOrigin);\n applyingParentUpdate = false;\n // ydoc-sync 也可能带 protocolVersion(兜底检测,正常情况 pong 已检测)\n if (type === \"ydoc-sync\" && event.data.protocolVersion != null) {\n if (event.data.protocolVersion >= 2 && !serverSupportsAck) {\n serverSupportsAck = true;\n log(\"server supports ack (protocol v\" + event.data.protocolVersion + \", via ydoc-sync)\");\n }\n } else if (type === \"ydoc-sync\" && !serverSupportsAck && !legacyMode) {\n // ydoc-sync 无 protocolVersion 且 pong 还没来 → 先切 legacy\n // 如果 pong 后来带 protocolVersion 会纠正回来\n legacyMode = true;\n unackedYdocUpdates.clear();\n log(\"legacy mode tentative: ydoc-sync has no protocolVersion\");\n }\n if (type === \"ydoc-sync\" && !connected) {\n setConnected(true);\n if (initRetryTimer) {\n clearInterval(initRetryTimer);\n initRetryTimer = null;\n }\n }\n } else if (type === \"awareness-sync\" || type === \"awareness-update\") {\n logMessage(\"recv\", type, payload);\n const prevLocalId = localClientId;\n if (receivedServerId != null) {\n serverClientId = receivedServerId;\n if (useExternalAwareness === false && receivedServerId != null && prevLocalId !== receivedServerId) {\n const tempState = localStates.get(prevLocalId);\n if (tempState) {\n localStates.delete(prevLocalId);\n localStates.set(receivedServerId, tempState);\n }\n }\n }\n\n if (useExternalAwareness) {\n const serverId = receivedServerId ?? serverClientId;\n const localId = awareness.clientID;\n \n applyingParentUpdate = true;\n if (serverId != null && serverId !== localId) {\n const remapped = remapClientIdInUpdate(\n new Uint8Array(payload),\n serverId,\n localId,\n );\n \n if (type === \"awareness-sync\") {\n (awareness as Awareness).meta.delete(localId);\n awareness.setLocalState(null);\n }\n \n applyAwarenessUpdate(awareness as Awareness, remapped, null);\n } else {\n applyAwarenessUpdate(awareness as Awareness, new Uint8Array(payload), null);\n }\n applyingParentUpdate = false;\n } else {\n const parsedStates = parseAwarenessPayload(new Uint8Array(payload));\n applyingParentUpdate = true;\n const changedClientIds: number[] = [];\n const removedClientIds: number[] = [];\n for (const [id, state] of parsedStates) {\n const existed = localStates.has(id);\n const changed = !existed || JSON.stringify(localStates.get(id)) !== JSON.stringify(state);\n localStates.set(id, state);\n if (changed) {\n changedClientIds.push(id);\n }\n }\n for (const [id] of localStates) {\n if (!parsedStates.has(id)) {\n localStates.delete(id);\n removedClientIds.push(id);\n }\n }\n if (changedClientIds.length > 0 || removedClientIds.length > 0) {\n const update = { added: [], updated: changedClientIds, removed: removedClientIds };\n updateHandlers.forEach(handler => handler(update));\n }\n applyingParentUpdate = false;\n }\n } else if (type === \"undo-state\") {\n if (!currentMxLike) {\n pendingUndoState = event.data;\n } else {\n syncUndoStateFromServer(currentMxLike, event.data);\n }\n } else if (type === \"disconnect\") {\n setConnected(false);\n startInitRetry();\n } else if (type === \"force-sync\") {\n // server 检测到不一致,强制发送完整 state\n log(\"received force-sync from server\");\n const fullState = Y.encodeStateAsUpdate(ydoc);\n parentPostMessage({ type: \"ydoc-pending-updates\", payload: [{ update: Array.from(fullState), isBaseline: false }] });\n }\n };\n\n ydoc.on(\"update\", onYdocUpdate);\n // 只有真正的 y-protocols Awareness 实例才有 .on() 方法\n // AwarenessLike(内部创建的)通过 updateHandlers 管理回调\n if (useExternalAwareness) {\n (awareness as Awareness).on(\"update\", onAwarenessUpdate);\n }\n window.addEventListener(\"message\", onMessage);\n\n startInitRetry();\n\n // 发送 ping 获取 serverClientId\n setTimeout(() => {\n window.parent.postMessage({ type: \"ping\" }, \"*\");\n }, 100);\n\n return {\n get serverClientId() {\n return serverClientId;\n },\n get connected() {\n return connected;\n },\n get awareness() {\n return awareness as Awareness;\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 setLocalFields(fields: Record<string, unknown>) {\n const currentLocal = awareness.getLocalState() || {};\n const currentUser = (currentLocal as { user?: Record<string, unknown> }).user || {};\n const newUser = { ...currentUser, ...fields };\n awareness.setLocalState({\n ...currentLocal,\n user: newUser,\n });\n // 通知父页面更新本地字段,父页面可选择是否处理\n if (connected) {\n const message = { type: \"set-local-fields\", fields };\n logMessage(\"send\", \"set-local-fields\", fields);\n window.parent.postMessage(message, \"*\");\n }\n },\n takeoverUndoManager(file: DrawioFile) {\n if (currentCleanup) {\n currentCleanup();\n }\n\n const editor = file.getUi().editor;\n const originUndoManager = editor.undoManager;\n\n // bindUndoManager 已安装:不替换 editor.undoManager,只委托 undo/redo\n if (originUndoManager && \"_y\" in originUndoManager) {\n const mxLike = originUndoManager as MxLike;\n const origUndo = mxLike.undo.bind(mxLike);\n const origRedo = mxLike.redo.bind(mxLike);\n const origCanUndo = mxLike.canUndo.bind(mxLike);\n const origCanRedo = mxLike.canRedo.bind(mxLike);\n currentMxLike = mxLike;\n mxLike.undo = () => {\n if (!applyingParentUpdate) {\n window.parent.postMessage({ type: \"undo\" }, \"*\");\n } else {\n origUndo();\n }\n };\n mxLike.redo = () => {\n if (!applyingParentUpdate) {\n window.parent.postMessage({ type: \"redo\" }, \"*\");\n } else {\n origRedo();\n }\n };\n mxLike.canUndo = () => mxLike.indexOfNextAdd > 0;\n mxLike.canRedo = () => mxLike.indexOfNextAdd < mxLike.history.length;\n if (pendingUndoState) {\n syncUndoStateFromServer(mxLike, pendingUndoState);\n pendingUndoState = null;\n }\n window.parent.postMessage({ type: \"request-undo-state\" }, \"*\");\n const cleanup = () => {\n mxLike.undo = origUndo;\n mxLike.redo = origRedo;\n mxLike.canUndo = origCanUndo;\n mxLike.canRedo = origCanRedo;\n currentMxLike = null;\n pendingUndoState = null;\n };\n currentCleanup = cleanup;\n return cleanup;\n }\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: MxLike = {\n eventListeners: [] as Array<string | ListenerFn>,\n history: [] as unknown[],\n indexOfNextAdd: 0,\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 \"\");\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(\n \"[iframe-bridge] undoManager event listener error:\",\n e,\n );\n }\n }\n }\n },\n\n canUndo(): boolean {\n return this.indexOfNextAdd > 0;\n },\n\n canRedo(): boolean {\n return this.indexOfNextAdd < this.history.length;\n },\n\n undo() {\n if (!applyingParentUpdate) {\n window.parent.postMessage({ type: \"undo\" }, \"*\");\n }\n },\n\n redo() {\n if (!applyingParentUpdate) {\n window.parent.postMessage({ type: \"redo\" }, \"*\");\n }\n },\n\n undoableEditHappened() {\n // no-op\n },\n };\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 currentMxLike = mxLike;\n editor.undoManager = mxLike as unknown as DrawioEditor[\"undoManager\"];\n editor.undoListener = function () {};\n\n if (pendingUndoState) {\n syncUndoStateFromServer(mxLike, pendingUndoState);\n pendingUndoState = null;\n }\n window.parent.postMessage({ type: \"request-undo-state\" }, \"*\");\n\n const cleanup = () => {\n editor.undoManager = originUndoManager;\n editor.undoListener = originUndoManager?.undoListener as\n | ((...args: unknown[]) => void)\n | undefined;\n currentMxLike = null;\n pendingUndoState = null;\n };\n\n currentCleanup = cleanup;\n return cleanup;\n },\n destroy: () => {\n while (pendingYdocUpdates.length > 0) {\n const { update, isBaseline } = pendingYdocUpdates.shift()!;\n window.parent.postMessage({ type: \"ydoc-update\", payload: Array.from(update), isBaseline }, \"*\");\n }\n unackedYdocUpdates.clear();\n ydoc.off(\"update\", onYdocUpdate);\n if (useExternalAwareness) {\n (awareness as Awareness).off(\"update\", onAwarenessUpdate);\n }\n window.removeEventListener(\"message\", onMessage);\n if (initRetryTimer) {\n clearInterval(initRetryTimer);\n initRetryTimer = null;\n }\n if (consistencyTimer) {\n clearInterval(consistencyTimer);\n consistencyTimer = null;\n }\n connectListeners.clear();\n disconnectListeners.clear();\n if (currentCleanup) {\n currentCleanup();\n }\n },\n };\n}\n"],"names":["awareness","Y","origin","localClientId","BASELINE_ORIGIN","IFRAME_ORIGIN","applyAwarenessUpdate","mxLike","cleanup"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as Y from "yjs";
|
|
2
2
|
import { applyAwarenessUpdate } from "y-protocols/awareness";
|
|
3
|
+
import { B as BASELINE_ORIGIN, I as IFRAME_ORIGIN } from "../origin-Doo2uLkM.js";
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __defProps = Object.defineProperties;
|
|
5
6
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
@@ -126,7 +127,7 @@ function parseAwarenessPayload(data) {
|
|
|
126
127
|
return result;
|
|
127
128
|
}
|
|
128
129
|
function createIframeBridgeProvider(ydoc, options) {
|
|
129
|
-
const { awareness: externalAwareness, debug = false } = options != null ? options : {};
|
|
130
|
+
const { awareness: externalAwareness, debug = false, consistencyCheckInterval = 0 } = options != null ? options : {};
|
|
130
131
|
let applyingParentUpdate = false;
|
|
131
132
|
let serverClientId = null;
|
|
132
133
|
let currentCleanup = null;
|
|
@@ -139,6 +140,7 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
139
140
|
let seq = 0;
|
|
140
141
|
const unackedYdocUpdates = /* @__PURE__ */ new Map();
|
|
141
142
|
let initRetryTimer = null;
|
|
143
|
+
let consistencyTimer = null;
|
|
142
144
|
let serverSupportsAck = false;
|
|
143
145
|
let legacyMode = false;
|
|
144
146
|
const connectListeners = /* @__PURE__ */ new Set();
|
|
@@ -260,6 +262,7 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
260
262
|
}
|
|
261
263
|
}
|
|
262
264
|
connectListeners.forEach((fn) => fn());
|
|
265
|
+
startConsistencyCheck();
|
|
263
266
|
} else {
|
|
264
267
|
lastLocalAwarenessSnapshot = null;
|
|
265
268
|
if (!legacyMode) {
|
|
@@ -293,6 +296,16 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
293
296
|
}
|
|
294
297
|
}, 1e3);
|
|
295
298
|
}
|
|
299
|
+
function startConsistencyCheck() {
|
|
300
|
+
if (consistencyTimer) clearInterval(consistencyTimer);
|
|
301
|
+
if (consistencyCheckInterval <= 0) return;
|
|
302
|
+
consistencyTimer = setInterval(() => {
|
|
303
|
+
if (!connected) return;
|
|
304
|
+
const sv = Y.encodeStateVector(ydoc);
|
|
305
|
+
parentPostMessage({ type: "consistency-check", stateVector: Array.from(sv) });
|
|
306
|
+
log("consistency-check sent");
|
|
307
|
+
}, consistencyCheckInterval);
|
|
308
|
+
}
|
|
296
309
|
const onYdocUpdate = (update, origin) => {
|
|
297
310
|
if (applyingParentUpdate) return;
|
|
298
311
|
const isBaseline = origin === null || origin === void 0;
|
|
@@ -399,7 +412,9 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
399
412
|
}
|
|
400
413
|
if (type === "ydoc-sync" || type === "ydoc-update") {
|
|
401
414
|
applyingParentUpdate = true;
|
|
402
|
-
|
|
415
|
+
const isBaseline = event.data && typeof event.data === "object" && event.data.isBaseline ? true : false;
|
|
416
|
+
const applyOrigin = isBaseline ? BASELINE_ORIGIN : IFRAME_ORIGIN;
|
|
417
|
+
Y.applyUpdate(ydoc, new Uint8Array(payload), applyOrigin);
|
|
403
418
|
applyingParentUpdate = false;
|
|
404
419
|
if (type === "ydoc-sync" && event.data.protocolVersion != null) {
|
|
405
420
|
if (event.data.protocolVersion >= 2 && !serverSupportsAck) {
|
|
@@ -484,6 +499,10 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
484
499
|
} else if (type === "disconnect") {
|
|
485
500
|
setConnected(false);
|
|
486
501
|
startInitRetry();
|
|
502
|
+
} else if (type === "force-sync") {
|
|
503
|
+
log("received force-sync from server");
|
|
504
|
+
const fullState = Y.encodeStateAsUpdate(ydoc);
|
|
505
|
+
parentPostMessage({ type: "ydoc-pending-updates", payload: [{ update: Array.from(fullState), isBaseline: false }] });
|
|
487
506
|
}
|
|
488
507
|
};
|
|
489
508
|
ydoc.on("update", onYdocUpdate);
|
|
@@ -670,6 +689,10 @@ function createIframeBridgeProvider(ydoc, options) {
|
|
|
670
689
|
clearInterval(initRetryTimer);
|
|
671
690
|
initRetryTimer = null;
|
|
672
691
|
}
|
|
692
|
+
if (consistencyTimer) {
|
|
693
|
+
clearInterval(consistencyTimer);
|
|
694
|
+
consistencyTimer = null;
|
|
695
|
+
}
|
|
673
696
|
connectListeners.clear();
|
|
674
697
|
disconnectListeners.clear();
|
|
675
698
|
if (currentCleanup) {
|