y-mxgraph 0.3.1 → 0.4.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/README.zh-CN.md +2 -2
- package/binding/index.d.ts +9 -1
- package/binding/index.d.ts.map +1 -1
- package/iframe-bridge/index.d.ts +2 -0
- package/iframe-bridge/index.d.ts.map +1 -0
- package/iframe-bridge/provider.cjs.js +246 -0
- package/iframe-bridge/provider.cjs.js.map +1 -0
- package/iframe-bridge/provider.es.js +229 -0
- package/iframe-bridge/provider.es.js.map +1 -0
- package/iframe-bridge/server.cjs.js +139 -0
- package/iframe-bridge/server.cjs.js.map +1 -0
- package/iframe-bridge/server.es.js +122 -0
- package/iframe-bridge/server.es.js.map +1 -0
- package/index.d.ts +1 -3
- package/index.d.ts.map +1 -1
- package/package.json +11 -3
- package/transformer/index.d.ts +2 -2
- package/transformer/index.d.ts.map +1 -1
- package/y-mxgraph.cjs.js +88 -168
- package/y-mxgraph.cjs.js.map +1 -1
- package/y-mxgraph.es.js +88 -162
- package/y-mxgraph.es.js.map +1 -1
- package/y-mxgraph.iife.js +0 -1758
- package/y-mxgraph.iife.js.map +0 -1
- package/y-mxgraph.umd.js +0 -1759
- package/y-mxgraph.umd.js.map +0 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const Y = require("yjs");
|
|
4
|
+
const awareness = require("y-protocols/awareness");
|
|
5
|
+
function _interopNamespaceDefault(e) {
|
|
6
|
+
const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
|
|
7
|
+
if (e) {
|
|
8
|
+
for (const k in e) {
|
|
9
|
+
if (k !== "default") {
|
|
10
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
11
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
12
|
+
enumerable: true,
|
|
13
|
+
get: () => e[k]
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
n.default = e;
|
|
19
|
+
return Object.freeze(n);
|
|
20
|
+
}
|
|
21
|
+
const Y__namespace = /* @__PURE__ */ _interopNamespaceDefault(Y);
|
|
22
|
+
const IFRAME_ORIGIN = {};
|
|
23
|
+
function createIframeBridgeServer(ydoc, awareness$1, options) {
|
|
24
|
+
const { undoManager } = options ?? {};
|
|
25
|
+
const iframes = /* @__PURE__ */ new Map();
|
|
26
|
+
const iframeReady = /* @__PURE__ */ new Set();
|
|
27
|
+
const onYdocUpdate = (update, origin) => {
|
|
28
|
+
if (origin === IFRAME_ORIGIN) return;
|
|
29
|
+
broadcastToAll("ydoc-update", update);
|
|
30
|
+
};
|
|
31
|
+
const onAwarenessUpdate = ({
|
|
32
|
+
added,
|
|
33
|
+
updated,
|
|
34
|
+
removed
|
|
35
|
+
}) => {
|
|
36
|
+
const changes = [...added, ...updated, ...removed];
|
|
37
|
+
if (changes.length === 0) return;
|
|
38
|
+
const update = awareness.encodeAwarenessUpdate(awareness$1, changes);
|
|
39
|
+
broadcastToAll("awareness-update", update);
|
|
40
|
+
};
|
|
41
|
+
function broadcastToAll(type, payload, excludeSource) {
|
|
42
|
+
for (const iframe of iframes.values()) {
|
|
43
|
+
if (iframe.contentWindow && iframe.contentWindow !== excludeSource) {
|
|
44
|
+
iframe.contentWindow.postMessage({ type, payload }, "*");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const onMessage = (event) => {
|
|
49
|
+
let iframeId = null;
|
|
50
|
+
for (const [id, iframe] of iframes) {
|
|
51
|
+
if (event.source === iframe.contentWindow) {
|
|
52
|
+
iframeId = id;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (!iframeId) return;
|
|
57
|
+
const { type: msgType, payload } = event.data;
|
|
58
|
+
const sourceWindow = event.source;
|
|
59
|
+
if (msgType === "init") {
|
|
60
|
+
if (!iframeReady.has(iframeId)) {
|
|
61
|
+
iframeReady.add(iframeId);
|
|
62
|
+
}
|
|
63
|
+
const docState = Y__namespace.encodeStateAsUpdate(ydoc);
|
|
64
|
+
const awarenessState = awareness.encodeAwarenessUpdate(
|
|
65
|
+
awareness$1,
|
|
66
|
+
Array.from(awareness$1.getStates().keys())
|
|
67
|
+
);
|
|
68
|
+
sourceWindow.postMessage(
|
|
69
|
+
{ type: "ydoc-sync", payload: Array.from(docState) },
|
|
70
|
+
"*"
|
|
71
|
+
);
|
|
72
|
+
sourceWindow.postMessage(
|
|
73
|
+
{
|
|
74
|
+
type: "awareness-sync",
|
|
75
|
+
payload: Array.from(awarenessState),
|
|
76
|
+
serverClientId: awareness$1.clientID
|
|
77
|
+
},
|
|
78
|
+
"*"
|
|
79
|
+
);
|
|
80
|
+
} else if (msgType === "ping") {
|
|
81
|
+
sourceWindow.postMessage(
|
|
82
|
+
{ type: "pong", serverClientId: awareness$1.clientID },
|
|
83
|
+
"*"
|
|
84
|
+
);
|
|
85
|
+
} else if (msgType === "ydoc-update") {
|
|
86
|
+
const update = new Uint8Array(payload);
|
|
87
|
+
Y__namespace.applyUpdate(ydoc, update, IFRAME_ORIGIN);
|
|
88
|
+
broadcastToAll("ydoc-update", update, sourceWindow);
|
|
89
|
+
} else if (msgType === "awareness-update") {
|
|
90
|
+
awareness.applyAwarenessUpdate(awareness$1, new Uint8Array(payload), null);
|
|
91
|
+
} else if (msgType === "undo" && undoManager) {
|
|
92
|
+
undoManager.undo();
|
|
93
|
+
} else if (msgType === "redo" && undoManager) {
|
|
94
|
+
undoManager.redo();
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
function addIframe(iframe, iframeId) {
|
|
98
|
+
iframes.set(iframeId, iframe);
|
|
99
|
+
}
|
|
100
|
+
function removeIframe(iframeId) {
|
|
101
|
+
iframes.delete(iframeId);
|
|
102
|
+
iframeReady.delete(iframeId);
|
|
103
|
+
}
|
|
104
|
+
const onUndoPopped = (e) => {
|
|
105
|
+
const t = e && (e.type || e.reason || e.kind);
|
|
106
|
+
if (t === "undo") {
|
|
107
|
+
broadcastToAll("undo", new Uint8Array());
|
|
108
|
+
} else if (t === "redo") {
|
|
109
|
+
broadcastToAll("redo", new Uint8Array());
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
const onStackCleared = () => {
|
|
113
|
+
broadcastToAll("clear", new Uint8Array());
|
|
114
|
+
};
|
|
115
|
+
ydoc.on("update", onYdocUpdate);
|
|
116
|
+
awareness$1.on("update", onAwarenessUpdate);
|
|
117
|
+
window.addEventListener("message", onMessage);
|
|
118
|
+
if (undoManager) {
|
|
119
|
+
undoManager.on("stack-item-popped", onUndoPopped);
|
|
120
|
+
undoManager.on("stack-cleared", onStackCleared);
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
addIframe,
|
|
124
|
+
removeIframe,
|
|
125
|
+
destroy: () => {
|
|
126
|
+
ydoc.off("update", onYdocUpdate);
|
|
127
|
+
awareness$1.off("update", onAwarenessUpdate);
|
|
128
|
+
window.removeEventListener("message", onMessage);
|
|
129
|
+
if (undoManager) {
|
|
130
|
+
undoManager.off("stack-item-popped", onUndoPopped);
|
|
131
|
+
undoManager.off("stack-cleared", onStackCleared);
|
|
132
|
+
}
|
|
133
|
+
iframes.clear();
|
|
134
|
+
iframeReady.clear();
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
exports.createIframeBridgeServer = createIframeBridgeServer;
|
|
139
|
+
//# sourceMappingURL=server.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.cjs.js","sources":["../../../iframe-bridge/src/origin.ts","../../../iframe-bridge/src/server.ts"],"sourcesContent":["/**\n * iframe bridge 内部变更的 origin 标识。\n * 当 provider 端产生 ydoc-update 时,使用此 origin 标记,\n * 以便 server 端的 UndoManager 能正确追踪来自 iframe 的变更。\n */\nexport const IFRAME_ORIGIN: object = {};\n","import * as Y from \"yjs\";\nimport {\n Awareness,\n applyAwarenessUpdate,\n encodeAwarenessUpdate,\n} from \"y-protocols/awareness\";\nimport { IFRAME_ORIGIN } from \"./origin.js\";\n\nexport interface IframeBridgeServerOptions {\n undoManager?: Y.UndoManager;\n}\n\nexport interface IframeBridgeServer {\n addIframe: (iframe: HTMLIFrameElement, iframeId: string) => void;\n removeIframe: (iframeId: string) => void;\n destroy: () => void;\n}\n\nexport function createIframeBridgeServer(\n ydoc: Y.Doc,\n awareness: Awareness,\n options?: IframeBridgeServerOptions,\n): IframeBridgeServer {\n const { undoManager } = options ?? {};\n const iframes = new Map<string, HTMLIFrameElement>();\n const iframeReady = new Set<string>();\n\n const onYdocUpdate = (update: Uint8Array, origin: unknown) => {\n if (origin === IFRAME_ORIGIN) return;\n broadcastToAll(\"ydoc-update\", update);\n };\n\n const onAwarenessUpdate = ({\n added,\n updated,\n removed,\n }: {\n added: number[];\n updated: number[];\n removed: number[];\n }) => {\n const changes = [...added, ...updated, ...removed];\n if (changes.length === 0) return;\n const update = encodeAwarenessUpdate(awareness, changes);\n broadcastToAll(\"awareness-update\", update);\n };\n\n function broadcastToAll(type: string, payload: Uint8Array, excludeSource?: Window) {\n for (const iframe of iframes.values()) {\n if (iframe.contentWindow && iframe.contentWindow !== excludeSource) {\n iframe.contentWindow.postMessage({ type, payload }, \"*\");\n }\n }\n }\n\n const onMessage = (event: MessageEvent) => {\n let iframeId: string | null = null;\n for (const [id, iframe] of iframes) {\n if (event.source === iframe.contentWindow) {\n iframeId = id;\n break;\n }\n }\n if (!iframeId) return;\n\n const { type: msgType, payload } = event.data;\n const sourceWindow = event.source as Window;\n\n if (msgType === \"init\") {\n if (!iframeReady.has(iframeId)) {\n iframeReady.add(iframeId);\n }\n const docState = Y.encodeStateAsUpdate(ydoc);\n const awarenessState = encodeAwarenessUpdate(\n awareness,\n Array.from(awareness.getStates().keys()),\n );\n sourceWindow.postMessage(\n { type: \"ydoc-sync\", payload: Array.from(docState) },\n \"*\",\n );\n sourceWindow.postMessage(\n {\n type: \"awareness-sync\",\n payload: Array.from(awarenessState),\n serverClientId: awareness.clientID,\n },\n \"*\",\n );\n } else if (msgType === \"ping\") {\n sourceWindow.postMessage(\n { type: \"pong\", serverClientId: awareness.clientID },\n \"*\",\n );\n } else if (msgType === \"ydoc-update\") {\n const update = new Uint8Array(payload);\n Y.applyUpdate(ydoc, update, IFRAME_ORIGIN);\n broadcastToAll(\"ydoc-update\", update, sourceWindow);\n } else if (msgType === \"awareness-update\") {\n applyAwarenessUpdate(awareness, new Uint8Array(payload), null);\n } else if (msgType === \"undo\" && undoManager) {\n undoManager.undo();\n } else if (msgType === \"redo\" && undoManager) {\n undoManager.redo();\n }\n };\n\n function addIframe(iframe: HTMLIFrameElement, iframeId: string) {\n iframes.set(iframeId, iframe);\n }\n\n function removeIframe(iframeId: string) {\n iframes.delete(iframeId);\n iframeReady.delete(iframeId);\n }\n\n const onUndoPopped = (e: { type?: string; reason?: string; kind?: string }) => {\n const t = e && (e.type || e.reason || e.kind);\n if (t === \"undo\") {\n broadcastToAll(\"undo\", new Uint8Array());\n } else if (t === \"redo\") {\n broadcastToAll(\"redo\", new Uint8Array());\n }\n };\n\n const onStackCleared = () => {\n broadcastToAll(\"clear\", new Uint8Array());\n };\n\n ydoc.on(\"update\", onYdocUpdate);\n awareness.on(\"update\", onAwarenessUpdate);\n window.addEventListener(\"message\", onMessage);\n if (undoManager) {\n undoManager.on(\"stack-item-popped\", onUndoPopped);\n undoManager.on(\"stack-cleared\", onStackCleared);\n }\n\n return {\n addIframe,\n removeIframe,\n destroy: () => {\n ydoc.off(\"update\", onYdocUpdate);\n awareness.off(\"update\", onAwarenessUpdate);\n window.removeEventListener(\"message\", onMessage);\n if (undoManager) {\n undoManager.off(\"stack-item-popped\", onUndoPopped);\n undoManager.off(\"stack-cleared\", onStackCleared);\n }\n iframes.clear();\n iframeReady.clear();\n },\n };\n}\n"],"names":["awareness","encodeAwarenessUpdate","Y","applyAwarenessUpdate"],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import * as Y from "yjs";
|
|
2
|
+
import { encodeAwarenessUpdate, applyAwarenessUpdate } from "y-protocols/awareness";
|
|
3
|
+
const IFRAME_ORIGIN = {};
|
|
4
|
+
function createIframeBridgeServer(ydoc, awareness, options) {
|
|
5
|
+
const { undoManager } = options ?? {};
|
|
6
|
+
const iframes = /* @__PURE__ */ new Map();
|
|
7
|
+
const iframeReady = /* @__PURE__ */ new Set();
|
|
8
|
+
const onYdocUpdate = (update, origin) => {
|
|
9
|
+
if (origin === IFRAME_ORIGIN) return;
|
|
10
|
+
broadcastToAll("ydoc-update", update);
|
|
11
|
+
};
|
|
12
|
+
const onAwarenessUpdate = ({
|
|
13
|
+
added,
|
|
14
|
+
updated,
|
|
15
|
+
removed
|
|
16
|
+
}) => {
|
|
17
|
+
const changes = [...added, ...updated, ...removed];
|
|
18
|
+
if (changes.length === 0) return;
|
|
19
|
+
const update = encodeAwarenessUpdate(awareness, changes);
|
|
20
|
+
broadcastToAll("awareness-update", update);
|
|
21
|
+
};
|
|
22
|
+
function broadcastToAll(type, payload, excludeSource) {
|
|
23
|
+
for (const iframe of iframes.values()) {
|
|
24
|
+
if (iframe.contentWindow && iframe.contentWindow !== excludeSource) {
|
|
25
|
+
iframe.contentWindow.postMessage({ type, payload }, "*");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const onMessage = (event) => {
|
|
30
|
+
let iframeId = null;
|
|
31
|
+
for (const [id, iframe] of iframes) {
|
|
32
|
+
if (event.source === iframe.contentWindow) {
|
|
33
|
+
iframeId = id;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!iframeId) return;
|
|
38
|
+
const { type: msgType, payload } = event.data;
|
|
39
|
+
const sourceWindow = event.source;
|
|
40
|
+
if (msgType === "init") {
|
|
41
|
+
if (!iframeReady.has(iframeId)) {
|
|
42
|
+
iframeReady.add(iframeId);
|
|
43
|
+
}
|
|
44
|
+
const docState = Y.encodeStateAsUpdate(ydoc);
|
|
45
|
+
const awarenessState = encodeAwarenessUpdate(
|
|
46
|
+
awareness,
|
|
47
|
+
Array.from(awareness.getStates().keys())
|
|
48
|
+
);
|
|
49
|
+
sourceWindow.postMessage(
|
|
50
|
+
{ type: "ydoc-sync", payload: Array.from(docState) },
|
|
51
|
+
"*"
|
|
52
|
+
);
|
|
53
|
+
sourceWindow.postMessage(
|
|
54
|
+
{
|
|
55
|
+
type: "awareness-sync",
|
|
56
|
+
payload: Array.from(awarenessState),
|
|
57
|
+
serverClientId: awareness.clientID
|
|
58
|
+
},
|
|
59
|
+
"*"
|
|
60
|
+
);
|
|
61
|
+
} else if (msgType === "ping") {
|
|
62
|
+
sourceWindow.postMessage(
|
|
63
|
+
{ type: "pong", serverClientId: awareness.clientID },
|
|
64
|
+
"*"
|
|
65
|
+
);
|
|
66
|
+
} else if (msgType === "ydoc-update") {
|
|
67
|
+
const update = new Uint8Array(payload);
|
|
68
|
+
Y.applyUpdate(ydoc, update, IFRAME_ORIGIN);
|
|
69
|
+
broadcastToAll("ydoc-update", update, sourceWindow);
|
|
70
|
+
} else if (msgType === "awareness-update") {
|
|
71
|
+
applyAwarenessUpdate(awareness, new Uint8Array(payload), null);
|
|
72
|
+
} else if (msgType === "undo" && undoManager) {
|
|
73
|
+
undoManager.undo();
|
|
74
|
+
} else if (msgType === "redo" && undoManager) {
|
|
75
|
+
undoManager.redo();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
function addIframe(iframe, iframeId) {
|
|
79
|
+
iframes.set(iframeId, iframe);
|
|
80
|
+
}
|
|
81
|
+
function removeIframe(iframeId) {
|
|
82
|
+
iframes.delete(iframeId);
|
|
83
|
+
iframeReady.delete(iframeId);
|
|
84
|
+
}
|
|
85
|
+
const onUndoPopped = (e) => {
|
|
86
|
+
const t = e && (e.type || e.reason || e.kind);
|
|
87
|
+
if (t === "undo") {
|
|
88
|
+
broadcastToAll("undo", new Uint8Array());
|
|
89
|
+
} else if (t === "redo") {
|
|
90
|
+
broadcastToAll("redo", new Uint8Array());
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
const onStackCleared = () => {
|
|
94
|
+
broadcastToAll("clear", new Uint8Array());
|
|
95
|
+
};
|
|
96
|
+
ydoc.on("update", onYdocUpdate);
|
|
97
|
+
awareness.on("update", onAwarenessUpdate);
|
|
98
|
+
window.addEventListener("message", onMessage);
|
|
99
|
+
if (undoManager) {
|
|
100
|
+
undoManager.on("stack-item-popped", onUndoPopped);
|
|
101
|
+
undoManager.on("stack-cleared", onStackCleared);
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
addIframe,
|
|
105
|
+
removeIframe,
|
|
106
|
+
destroy: () => {
|
|
107
|
+
ydoc.off("update", onYdocUpdate);
|
|
108
|
+
awareness.off("update", onAwarenessUpdate);
|
|
109
|
+
window.removeEventListener("message", onMessage);
|
|
110
|
+
if (undoManager) {
|
|
111
|
+
undoManager.off("stack-item-popped", onUndoPopped);
|
|
112
|
+
undoManager.off("stack-cleared", onStackCleared);
|
|
113
|
+
}
|
|
114
|
+
iframes.clear();
|
|
115
|
+
iframeReady.clear();
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export {
|
|
120
|
+
createIframeBridgeServer
|
|
121
|
+
};
|
|
122
|
+
//# sourceMappingURL=server.es.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.es.js","sources":["../../../iframe-bridge/src/origin.ts","../../../iframe-bridge/src/server.ts"],"sourcesContent":["/**\n * iframe bridge 内部变更的 origin 标识。\n * 当 provider 端产生 ydoc-update 时,使用此 origin 标记,\n * 以便 server 端的 UndoManager 能正确追踪来自 iframe 的变更。\n */\nexport const IFRAME_ORIGIN: object = {};\n","import * as Y from \"yjs\";\nimport {\n Awareness,\n applyAwarenessUpdate,\n encodeAwarenessUpdate,\n} from \"y-protocols/awareness\";\nimport { IFRAME_ORIGIN } from \"./origin.js\";\n\nexport interface IframeBridgeServerOptions {\n undoManager?: Y.UndoManager;\n}\n\nexport interface IframeBridgeServer {\n addIframe: (iframe: HTMLIFrameElement, iframeId: string) => void;\n removeIframe: (iframeId: string) => void;\n destroy: () => void;\n}\n\nexport function createIframeBridgeServer(\n ydoc: Y.Doc,\n awareness: Awareness,\n options?: IframeBridgeServerOptions,\n): IframeBridgeServer {\n const { undoManager } = options ?? {};\n const iframes = new Map<string, HTMLIFrameElement>();\n const iframeReady = new Set<string>();\n\n const onYdocUpdate = (update: Uint8Array, origin: unknown) => {\n if (origin === IFRAME_ORIGIN) return;\n broadcastToAll(\"ydoc-update\", update);\n };\n\n const onAwarenessUpdate = ({\n added,\n updated,\n removed,\n }: {\n added: number[];\n updated: number[];\n removed: number[];\n }) => {\n const changes = [...added, ...updated, ...removed];\n if (changes.length === 0) return;\n const update = encodeAwarenessUpdate(awareness, changes);\n broadcastToAll(\"awareness-update\", update);\n };\n\n function broadcastToAll(type: string, payload: Uint8Array, excludeSource?: Window) {\n for (const iframe of iframes.values()) {\n if (iframe.contentWindow && iframe.contentWindow !== excludeSource) {\n iframe.contentWindow.postMessage({ type, payload }, \"*\");\n }\n }\n }\n\n const onMessage = (event: MessageEvent) => {\n let iframeId: string | null = null;\n for (const [id, iframe] of iframes) {\n if (event.source === iframe.contentWindow) {\n iframeId = id;\n break;\n }\n }\n if (!iframeId) return;\n\n const { type: msgType, payload } = event.data;\n const sourceWindow = event.source as Window;\n\n if (msgType === \"init\") {\n if (!iframeReady.has(iframeId)) {\n iframeReady.add(iframeId);\n }\n const docState = Y.encodeStateAsUpdate(ydoc);\n const awarenessState = encodeAwarenessUpdate(\n awareness,\n Array.from(awareness.getStates().keys()),\n );\n sourceWindow.postMessage(\n { type: \"ydoc-sync\", payload: Array.from(docState) },\n \"*\",\n );\n sourceWindow.postMessage(\n {\n type: \"awareness-sync\",\n payload: Array.from(awarenessState),\n serverClientId: awareness.clientID,\n },\n \"*\",\n );\n } else if (msgType === \"ping\") {\n sourceWindow.postMessage(\n { type: \"pong\", serverClientId: awareness.clientID },\n \"*\",\n );\n } else if (msgType === \"ydoc-update\") {\n const update = new Uint8Array(payload);\n Y.applyUpdate(ydoc, update, IFRAME_ORIGIN);\n broadcastToAll(\"ydoc-update\", update, sourceWindow);\n } else if (msgType === \"awareness-update\") {\n applyAwarenessUpdate(awareness, new Uint8Array(payload), null);\n } else if (msgType === \"undo\" && undoManager) {\n undoManager.undo();\n } else if (msgType === \"redo\" && undoManager) {\n undoManager.redo();\n }\n };\n\n function addIframe(iframe: HTMLIFrameElement, iframeId: string) {\n iframes.set(iframeId, iframe);\n }\n\n function removeIframe(iframeId: string) {\n iframes.delete(iframeId);\n iframeReady.delete(iframeId);\n }\n\n const onUndoPopped = (e: { type?: string; reason?: string; kind?: string }) => {\n const t = e && (e.type || e.reason || e.kind);\n if (t === \"undo\") {\n broadcastToAll(\"undo\", new Uint8Array());\n } else if (t === \"redo\") {\n broadcastToAll(\"redo\", new Uint8Array());\n }\n };\n\n const onStackCleared = () => {\n broadcastToAll(\"clear\", new Uint8Array());\n };\n\n ydoc.on(\"update\", onYdocUpdate);\n awareness.on(\"update\", onAwarenessUpdate);\n window.addEventListener(\"message\", onMessage);\n if (undoManager) {\n undoManager.on(\"stack-item-popped\", onUndoPopped);\n undoManager.on(\"stack-cleared\", onStackCleared);\n }\n\n return {\n addIframe,\n removeIframe,\n destroy: () => {\n ydoc.off(\"update\", onYdocUpdate);\n awareness.off(\"update\", onAwarenessUpdate);\n window.removeEventListener(\"message\", onMessage);\n if (undoManager) {\n undoManager.off(\"stack-item-popped\", onUndoPopped);\n undoManager.off(\"stack-cleared\", onStackCleared);\n }\n iframes.clear();\n iframeReady.clear();\n },\n };\n}\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
export { Binding } from "./binding";
|
|
2
2
|
export type { BindDrawioFileOptions, InitialContentStrategy } from "./binding";
|
|
3
|
-
export {
|
|
3
|
+
export { xml2ydoc, ydoc2xml } from "./transformer";
|
|
4
4
|
export { LOCAL_ORIGIN } from "./helper/origin";
|
|
5
5
|
export { DEFAULT_USER_NAME_KEY, DEFAULT_USER_COLOR_KEY, } from "./binding/collaborator";
|
|
6
|
-
export { createIframeBridgeProvider, createIframeBridgeServer, } from "@y-mxgraph/iframe-bridge";
|
|
7
|
-
export type { IframeBridgeProvider, IframeBridgeServer, } from "@y-mxgraph/iframe-bridge";
|
|
8
6
|
//# sourceMappingURL=index.d.ts.map
|
package/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAC/E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "y-mxgraph",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Yjs binding for draw.io (mxGraph) documents",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"yjs",
|
|
@@ -18,14 +18,22 @@
|
|
|
18
18
|
"type": "module",
|
|
19
19
|
"main": "./y-mxgraph.cjs.js",
|
|
20
20
|
"module": "./y-mxgraph.es.js",
|
|
21
|
-
"browser": "./y-mxgraph.umd.js",
|
|
22
21
|
"types": "./index.d.ts",
|
|
23
22
|
"exports": {
|
|
24
23
|
".": {
|
|
25
24
|
"import": "./y-mxgraph.es.js",
|
|
26
25
|
"require": "./y-mxgraph.cjs.js",
|
|
27
|
-
"browser": "./y-mxgraph.umd.js",
|
|
28
26
|
"types": "./index.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./iframe-bridge/server": {
|
|
29
|
+
"import": "./iframe-bridge/server.es.js",
|
|
30
|
+
"require": "./iframe-bridge/server.cjs.js",
|
|
31
|
+
"types": "./iframe-bridge/server.d.ts"
|
|
32
|
+
},
|
|
33
|
+
"./iframe-bridge/provider": {
|
|
34
|
+
"import": "./iframe-bridge/provider.es.js",
|
|
35
|
+
"require": "./iframe-bridge/provider.cjs.js",
|
|
36
|
+
"types": "./iframe-bridge/provider.d.ts"
|
|
29
37
|
}
|
|
30
38
|
},
|
|
31
39
|
"dependencies": {
|
package/transformer/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import * as Y from "yjs";
|
|
2
|
-
export declare function
|
|
3
|
-
export declare function
|
|
2
|
+
export declare function xml2ydoc(xml: string, doc: Y.Doc): Y.Doc;
|
|
3
|
+
export declare function ydoc2xml(doc: Y.Doc, spaces?: number): string;
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transformer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAezB,wBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transformer/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAezB,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAkBvD;AAED,wBAAgB,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,SAAI,GAAG,MAAM,CAsBvD"}
|