@vervedoc/docx-editor-collaboration 1.0.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.
@@ -0,0 +1,1019 @@
1
+ var W = Object.defineProperty;
2
+ var q = (t, e, r) => e in t ? W(t, e, { enumerable: !0, configurable: !0, writable: !0, value: r }) : t[e] = r;
3
+ var d = (t, e, r) => q(t, typeof e != "symbol" ? e + "" : e, r);
4
+ import * as D from "yjs";
5
+ import { HocuspocusProvider as X } from "@hocuspocus/provider";
6
+ var C = /* @__PURE__ */ ((t) => (t.DISCONNECTED = "disconnected", t.CONNECTING = "connecting", t.CONNECTED = "connected", t))(C || {}), R = /* @__PURE__ */ ((t) => (t.SYNCING = "syncing", t.SYNCED = "synced", t))(R || {});
7
+ /*!
8
+ * https://github.com/Starcounter-Jack/JSON-Patch
9
+ * (c) 2017-2022 Joachim Wester
10
+ * MIT licensed
11
+ */
12
+ var Z = /* @__PURE__ */ function() {
13
+ var t = function(e, r) {
14
+ return t = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(n, s) {
15
+ n.__proto__ = s;
16
+ } || function(n, s) {
17
+ for (var i in s) s.hasOwnProperty(i) && (n[i] = s[i]);
18
+ }, t(e, r);
19
+ };
20
+ return function(e, r) {
21
+ t(e, r);
22
+ function n() {
23
+ this.constructor = e;
24
+ }
25
+ e.prototype = r === null ? Object.create(r) : (n.prototype = r.prototype, new n());
26
+ };
27
+ }(), V = Object.prototype.hasOwnProperty;
28
+ function P(t, e) {
29
+ return V.call(t, e);
30
+ }
31
+ function x(t) {
32
+ if (Array.isArray(t)) {
33
+ for (var e = new Array(t.length), r = 0; r < e.length; r++)
34
+ e[r] = "" + r;
35
+ return e;
36
+ }
37
+ if (Object.keys)
38
+ return Object.keys(t);
39
+ var n = [];
40
+ for (var s in t)
41
+ P(t, s) && n.push(s);
42
+ return n;
43
+ }
44
+ function w(t) {
45
+ switch (typeof t) {
46
+ case "object":
47
+ return JSON.parse(JSON.stringify(t));
48
+ //Faster than ES5 clone - http://jsperf.com/deep-cloning-of-objects/5
49
+ case "undefined":
50
+ return null;
51
+ //this is how JSON.stringify behaves for array items
52
+ default:
53
+ return t;
54
+ }
55
+ }
56
+ function M(t) {
57
+ for (var e = 0, r = t.length, n; e < r; ) {
58
+ if (n = t.charCodeAt(e), n >= 48 && n <= 57) {
59
+ e++;
60
+ continue;
61
+ }
62
+ return !1;
63
+ }
64
+ return !0;
65
+ }
66
+ function O(t) {
67
+ return t.indexOf("/") === -1 && t.indexOf("~") === -1 ? t : t.replace(/~/g, "~0").replace(/\//g, "~1");
68
+ }
69
+ function j(t) {
70
+ return t.replace(/~1/g, "/").replace(/~0/g, "~");
71
+ }
72
+ function U(t) {
73
+ if (t === void 0)
74
+ return !0;
75
+ if (t) {
76
+ if (Array.isArray(t)) {
77
+ for (var e = 0, r = t.length; e < r; e++)
78
+ if (U(t[e]))
79
+ return !0;
80
+ } else if (typeof t == "object") {
81
+ for (var n = x(t), s = n.length, i = 0; i < s; i++)
82
+ if (U(t[n[i]]))
83
+ return !0;
84
+ }
85
+ }
86
+ return !1;
87
+ }
88
+ function z(t, e) {
89
+ var r = [t];
90
+ for (var n in e) {
91
+ var s = typeof e[n] == "object" ? JSON.stringify(e[n], null, 2) : e[n];
92
+ typeof s < "u" && r.push(n + ": " + s);
93
+ }
94
+ return r.join(`
95
+ `);
96
+ }
97
+ var G = (
98
+ /** @class */
99
+ function(t) {
100
+ Z(e, t);
101
+ function e(r, n, s, i, a) {
102
+ var u = this.constructor, c = t.call(this, z(r, { name: n, index: s, operation: i, tree: a })) || this;
103
+ return c.name = n, c.index = s, c.operation = i, c.tree = a, Object.setPrototypeOf(c, u.prototype), c.message = z(r, { name: n, index: s, operation: i, tree: a }), c;
104
+ }
105
+ return e;
106
+ }(Error)
107
+ ), m = G, k = w, N = {
108
+ add: function(t, e, r) {
109
+ return t[e] = this.value, { newDocument: r };
110
+ },
111
+ remove: function(t, e, r) {
112
+ var n = t[e];
113
+ return delete t[e], { newDocument: r, removed: n };
114
+ },
115
+ replace: function(t, e, r) {
116
+ var n = t[e];
117
+ return t[e] = this.value, { newDocument: r, removed: n };
118
+ },
119
+ move: function(t, e, r) {
120
+ var n = I(r, this.path);
121
+ n && (n = w(n));
122
+ var s = A(r, { op: "remove", path: this.from }).removed;
123
+ return A(r, { op: "add", path: this.path, value: s }), { newDocument: r, removed: n };
124
+ },
125
+ copy: function(t, e, r) {
126
+ var n = I(r, this.from);
127
+ return A(r, { op: "add", path: this.path, value: w(n) }), { newDocument: r };
128
+ },
129
+ test: function(t, e, r) {
130
+ return { newDocument: r, test: S(t[e], this.value) };
131
+ },
132
+ _get: function(t, e, r) {
133
+ return this.value = t[e], { newDocument: r };
134
+ }
135
+ }, ee = {
136
+ add: function(t, e, r) {
137
+ return M(e) ? t.splice(e, 0, this.value) : t[e] = this.value, { newDocument: r, index: e };
138
+ },
139
+ remove: function(t, e, r) {
140
+ var n = t.splice(e, 1);
141
+ return { newDocument: r, removed: n[0] };
142
+ },
143
+ replace: function(t, e, r) {
144
+ var n = t[e];
145
+ return t[e] = this.value, { newDocument: r, removed: n };
146
+ },
147
+ move: N.move,
148
+ copy: N.copy,
149
+ test: N.test,
150
+ _get: N._get
151
+ };
152
+ function I(t, e) {
153
+ if (e == "")
154
+ return t;
155
+ var r = { op: "_get", path: e };
156
+ return A(t, r), r.value;
157
+ }
158
+ function A(t, e, r, n, s, i) {
159
+ if (r === void 0 && (r = !1), n === void 0 && (n = !0), s === void 0 && (s = !0), i === void 0 && (i = 0), r && (typeof r == "function" ? r(e, 0, t, e.path) : L(e, 0)), e.path === "") {
160
+ var a = { newDocument: t };
161
+ if (e.op === "add")
162
+ return a.newDocument = e.value, a;
163
+ if (e.op === "replace")
164
+ return a.newDocument = e.value, a.removed = t, a;
165
+ if (e.op === "move" || e.op === "copy")
166
+ return a.newDocument = I(t, e.from), e.op === "move" && (a.removed = t), a;
167
+ if (e.op === "test") {
168
+ if (a.test = S(t, e.value), a.test === !1)
169
+ throw new m("Test operation failed", "TEST_OPERATION_FAILED", i, e, t);
170
+ return a.newDocument = t, a;
171
+ } else {
172
+ if (e.op === "remove")
173
+ return a.removed = t, a.newDocument = null, a;
174
+ if (e.op === "_get")
175
+ return e.value = t, a;
176
+ if (r)
177
+ throw new m("Operation `op` property is not one of operations defined in RFC-6902", "OPERATION_OP_INVALID", i, e, t);
178
+ return a;
179
+ }
180
+ } else {
181
+ n || (t = w(t));
182
+ var u = e.path || "", c = u.split("/"), o = t, l = 1, f = c.length, g = void 0, p = void 0, v = void 0;
183
+ for (typeof r == "function" ? v = r : v = L; ; ) {
184
+ if (p = c[l], p && p.indexOf("~") != -1 && (p = j(p)), s && (p == "__proto__" || p == "prototype" && l > 0 && c[l - 1] == "constructor"))
185
+ throw new TypeError("JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README");
186
+ if (r && g === void 0 && (o[p] === void 0 ? g = c.slice(0, l).join("/") : l == f - 1 && (g = e.path), g !== void 0 && v(e, 0, t, g)), l++, Array.isArray(o)) {
187
+ if (p === "-")
188
+ p = o.length;
189
+ else {
190
+ if (r && !M(p))
191
+ throw new m("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index", "OPERATION_PATH_ILLEGAL_ARRAY_INDEX", i, e, t);
192
+ M(p) && (p = ~~p);
193
+ }
194
+ if (l >= f) {
195
+ if (r && e.op === "add" && p > o.length)
196
+ throw new m("The specified index MUST NOT be greater than the number of elements in the array", "OPERATION_VALUE_OUT_OF_BOUNDS", i, e, t);
197
+ var a = ee[e.op].call(e, o, p, t);
198
+ if (a.test === !1)
199
+ throw new m("Test operation failed", "TEST_OPERATION_FAILED", i, e, t);
200
+ return a;
201
+ }
202
+ } else if (l >= f) {
203
+ var a = N[e.op].call(e, o, p, t);
204
+ if (a.test === !1)
205
+ throw new m("Test operation failed", "TEST_OPERATION_FAILED", i, e, t);
206
+ return a;
207
+ }
208
+ if (o = o[p], r && l < f && (!o || typeof o != "object"))
209
+ throw new m("Cannot perform operation at the desired path", "OPERATION_PATH_UNRESOLVABLE", i, e, t);
210
+ }
211
+ }
212
+ }
213
+ function H(t, e, r, n, s) {
214
+ if (n === void 0 && (n = !0), s === void 0 && (s = !0), r && !Array.isArray(e))
215
+ throw new m("Patch sequence must be an array", "SEQUENCE_NOT_AN_ARRAY");
216
+ n || (t = w(t));
217
+ for (var i = new Array(e.length), a = 0, u = e.length; a < u; a++)
218
+ i[a] = A(t, e[a], r, !0, s, a), t = i[a].newDocument;
219
+ return i.newDocument = t, i;
220
+ }
221
+ function te(t, e, r) {
222
+ var n = A(t, e);
223
+ if (n.test === !1)
224
+ throw new m("Test operation failed", "TEST_OPERATION_FAILED", r, e, t);
225
+ return n.newDocument;
226
+ }
227
+ function L(t, e, r, n) {
228
+ if (typeof t != "object" || t === null || Array.isArray(t))
229
+ throw new m("Operation is not an object", "OPERATION_NOT_AN_OBJECT", e, t, r);
230
+ if (N[t.op]) {
231
+ if (typeof t.path != "string")
232
+ throw new m("Operation `path` property is not a string", "OPERATION_PATH_INVALID", e, t, r);
233
+ if (t.path.indexOf("/") !== 0 && t.path.length > 0)
234
+ throw new m('Operation `path` property must start with "/"', "OPERATION_PATH_INVALID", e, t, r);
235
+ if ((t.op === "move" || t.op === "copy") && typeof t.from != "string")
236
+ throw new m("Operation `from` property is not present (applicable in `move` and `copy` operations)", "OPERATION_FROM_REQUIRED", e, t, r);
237
+ if ((t.op === "add" || t.op === "replace" || t.op === "test") && t.value === void 0)
238
+ throw new m("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)", "OPERATION_VALUE_REQUIRED", e, t, r);
239
+ if ((t.op === "add" || t.op === "replace" || t.op === "test") && U(t.value))
240
+ throw new m("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)", "OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED", e, t, r);
241
+ if (r) {
242
+ if (t.op == "add") {
243
+ var s = t.path.split("/").length, i = n.split("/").length;
244
+ if (s !== i + 1 && s !== i)
245
+ throw new m("Cannot perform an `add` operation at the desired path", "OPERATION_PATH_CANNOT_ADD", e, t, r);
246
+ } else if (t.op === "replace" || t.op === "remove" || t.op === "_get") {
247
+ if (t.path !== n)
248
+ throw new m("Cannot perform the operation at a path that does not exist", "OPERATION_PATH_UNRESOLVABLE", e, t, r);
249
+ } else if (t.op === "move" || t.op === "copy") {
250
+ var a = { op: "_get", path: t.from, value: void 0 }, u = B([a], r);
251
+ if (u && u.name === "OPERATION_PATH_UNRESOLVABLE")
252
+ throw new m("Cannot perform the operation from a path that does not exist", "OPERATION_FROM_UNRESOLVABLE", e, t, r);
253
+ }
254
+ }
255
+ } else throw new m("Operation `op` property is not one of operations defined in RFC-6902", "OPERATION_OP_INVALID", e, t, r);
256
+ }
257
+ function B(t, e, r) {
258
+ try {
259
+ if (!Array.isArray(t))
260
+ throw new m("Patch sequence must be an array", "SEQUENCE_NOT_AN_ARRAY");
261
+ if (e)
262
+ H(w(e), w(t), r || !0);
263
+ else {
264
+ r = r || L;
265
+ for (var n = 0; n < t.length; n++)
266
+ r(t[n], n, e, void 0);
267
+ }
268
+ } catch (s) {
269
+ if (s instanceof m)
270
+ return s;
271
+ throw s;
272
+ }
273
+ }
274
+ function S(t, e) {
275
+ if (t === e)
276
+ return !0;
277
+ if (t && e && typeof t == "object" && typeof e == "object") {
278
+ var r = Array.isArray(t), n = Array.isArray(e), s, i, a;
279
+ if (r && n) {
280
+ if (i = t.length, i != e.length)
281
+ return !1;
282
+ for (s = i; s-- !== 0; )
283
+ if (!S(t[s], e[s]))
284
+ return !1;
285
+ return !0;
286
+ }
287
+ if (r != n)
288
+ return !1;
289
+ var u = Object.keys(t);
290
+ if (i = u.length, i !== Object.keys(e).length)
291
+ return !1;
292
+ for (s = i; s-- !== 0; )
293
+ if (!e.hasOwnProperty(u[s]))
294
+ return !1;
295
+ for (s = i; s-- !== 0; )
296
+ if (a = u[s], !S(t[a], e[a]))
297
+ return !1;
298
+ return !0;
299
+ }
300
+ return t !== t && e !== e;
301
+ }
302
+ const re = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
303
+ __proto__: null,
304
+ JsonPatchError: m,
305
+ _areEquals: S,
306
+ applyOperation: A,
307
+ applyPatch: H,
308
+ applyReducer: te,
309
+ deepClone: k,
310
+ getValueByPointer: I,
311
+ validate: B,
312
+ validator: L
313
+ }, Symbol.toStringTag, { value: "Module" }));
314
+ /*!
315
+ * https://github.com/Starcounter-Jack/JSON-Patch
316
+ * (c) 2017-2021 Joachim Wester
317
+ * MIT license
318
+ */
319
+ var F = /* @__PURE__ */ new WeakMap(), ne = (
320
+ /** @class */
321
+ /* @__PURE__ */ function() {
322
+ function t(e) {
323
+ this.observers = /* @__PURE__ */ new Map(), this.obj = e;
324
+ }
325
+ return t;
326
+ }()
327
+ ), se = (
328
+ /** @class */
329
+ /* @__PURE__ */ function() {
330
+ function t(e, r) {
331
+ this.callback = e, this.observer = r;
332
+ }
333
+ return t;
334
+ }()
335
+ );
336
+ function ie(t) {
337
+ return F.get(t);
338
+ }
339
+ function oe(t, e) {
340
+ return t.observers.get(e);
341
+ }
342
+ function le(t, e) {
343
+ t.observers.delete(e.callback);
344
+ }
345
+ function ae(t, e) {
346
+ e.unobserve();
347
+ }
348
+ function ce(t, e) {
349
+ var r = [], n, s = ie(t);
350
+ if (!s)
351
+ s = new ne(t), F.set(t, s);
352
+ else {
353
+ var i = oe(s, e);
354
+ n = i && i.observer;
355
+ }
356
+ if (n)
357
+ return n;
358
+ if (n = {}, s.value = w(t), e) {
359
+ n.callback = e, n.next = null;
360
+ var a = function() {
361
+ Y(n);
362
+ }, u = function() {
363
+ clearTimeout(n.next), n.next = setTimeout(a);
364
+ };
365
+ typeof window < "u" && (window.addEventListener("mouseup", u), window.addEventListener("keyup", u), window.addEventListener("mousedown", u), window.addEventListener("keydown", u), window.addEventListener("change", u));
366
+ }
367
+ return n.patches = r, n.object = t, n.unobserve = function() {
368
+ Y(n), clearTimeout(n.next), le(s, n), typeof window < "u" && (window.removeEventListener("mouseup", u), window.removeEventListener("keyup", u), window.removeEventListener("mousedown", u), window.removeEventListener("keydown", u), window.removeEventListener("change", u));
369
+ }, s.observers.set(e, new se(e, n)), n;
370
+ }
371
+ function Y(t, e) {
372
+ e === void 0 && (e = !1);
373
+ var r = F.get(t.object);
374
+ J(r.value, t.object, t.patches, "", e), t.patches.length && H(r.value, t.patches);
375
+ var n = t.patches;
376
+ return n.length > 0 && (t.patches = [], t.callback && t.callback(n)), n;
377
+ }
378
+ function J(t, e, r, n, s) {
379
+ if (e !== t) {
380
+ typeof e.toJSON == "function" && (e = e.toJSON());
381
+ for (var i = x(e), a = x(t), u = !1, c = a.length - 1; c >= 0; c--) {
382
+ var o = a[c], l = t[o];
383
+ if (P(e, o) && !(e[o] === void 0 && l !== void 0 && Array.isArray(e) === !1)) {
384
+ var f = e[o];
385
+ typeof l == "object" && l != null && typeof f == "object" && f != null && Array.isArray(l) === Array.isArray(f) ? J(l, f, r, n + "/" + O(o), s) : l !== f && (s && r.push({ op: "test", path: n + "/" + O(o), value: w(l) }), r.push({ op: "replace", path: n + "/" + O(o), value: w(f) }));
386
+ } else Array.isArray(t) === Array.isArray(e) ? (s && r.push({ op: "test", path: n + "/" + O(o), value: w(l) }), r.push({ op: "remove", path: n + "/" + O(o) }), u = !0) : (s && r.push({ op: "test", path: n, value: t }), r.push({ op: "replace", path: n, value: e }));
387
+ }
388
+ if (!(!u && i.length == a.length))
389
+ for (var c = 0; c < i.length; c++) {
390
+ var o = i[c];
391
+ !P(t, o) && e[o] !== void 0 && r.push({ op: "add", path: n + "/" + O(o), value: w(e[o]) });
392
+ }
393
+ }
394
+ }
395
+ function $(t, e, r) {
396
+ r === void 0 && (r = !1);
397
+ var n = [];
398
+ return J(t, e, n, "", r), n;
399
+ }
400
+ const ue = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
401
+ __proto__: null,
402
+ compare: $,
403
+ generate: Y,
404
+ observe: ce,
405
+ unobserve: ae
406
+ }, Symbol.toStringTag, { value: "Module" }));
407
+ Object.assign({}, re, ue, {
408
+ JsonPatchError: G,
409
+ deepClone: w,
410
+ escapePathComponent: O,
411
+ unescapePathComponent: j
412
+ });
413
+ const fe = /* @__PURE__ */ new Set([
414
+ "valueList",
415
+ "trList",
416
+ "tdList",
417
+ "colgroup"
418
+ ]);
419
+ function he(t, e, r) {
420
+ return typeof t.select == "function" ? t.select(e).subscribe(r) : typeof t.on == "function" ? (t.on(e, r), {
421
+ unsubscribe: () => {
422
+ typeof t.off == "function" && t.off(e, r);
423
+ }
424
+ }) : { unsubscribe: () => {
425
+ } };
426
+ }
427
+ class pe {
428
+ constructor(e, r) {
429
+ d(this, "doc");
430
+ d(this, "editor");
431
+ d(this, "yElements");
432
+ /** 是否正在把远程变更写入编辑器(防回环) */
433
+ d(this, "isApplyingRemote", !1);
434
+ /** 是否正在把本地编辑写入 Y.Doc(防回环) */
435
+ d(this, "isApplyingLocal", !1);
436
+ /** 上一次同步到编辑器的快照(用于 diff) */
437
+ d(this, "lastSnapshot", []);
438
+ /** 编辑器事件回调引用 */
439
+ d(this, "contentChangeHandler", null);
440
+ d(this, "contentChangeSubscription", null);
441
+ /** Y.Array observe 回调引用 */
442
+ d(this, "yObserver", null);
443
+ this.doc = e, this.editor = r, this.yElements = e.getArray("elements"), this.bindYjsToEditor(), this.bindEditorToYjs(), this.yElements.length > 0 && this.pushYDocToEditor();
444
+ }
445
+ destroy() {
446
+ var e;
447
+ this.yObserver && (this.yElements.unobserve(this.yObserver), this.yObserver = null), (e = this.contentChangeSubscription) == null || e.unsubscribe(), this.contentChangeSubscription = null, this.contentChangeHandler = null;
448
+ }
449
+ // ---- Y.Doc → Editor ----
450
+ bindYjsToEditor() {
451
+ this.yObserver = (e, r) => {
452
+ this.isApplyingLocal || r.local || this.pushYDocToEditor();
453
+ }, this.yElements.observeDeep(this.yObserver);
454
+ }
455
+ /** 将 Y.Doc 当前内容推送到编辑器 */
456
+ pushYDocToEditor() {
457
+ this.isApplyingRemote = !0;
458
+ try {
459
+ const e = this.yElements.toJSON();
460
+ this.editor.command.executeSetValue({ main: e }, { isSetCursor: !1 }), this.lastSnapshot = e;
461
+ } finally {
462
+ this.isApplyingRemote = !1;
463
+ }
464
+ }
465
+ // ---- Editor → Y.Doc ----
466
+ bindEditorToYjs() {
467
+ this.contentChangeHandler = () => {
468
+ this.isApplyingRemote || this.pushEditorToYDoc();
469
+ }, this.contentChangeSubscription = he(
470
+ this.editor.eventBus,
471
+ "contentChange",
472
+ this.contentChangeHandler
473
+ );
474
+ }
475
+ /** 将编辑器当前内容全量同步到 Y.Doc */
476
+ pushEditorToYDoc() {
477
+ const r = this.editor.command.getValue().data.main ?? [], n = $(this.lastSnapshot, r);
478
+ if (n.length) {
479
+ this.isApplyingLocal = !0;
480
+ try {
481
+ this.doc.transact(() => {
482
+ this.applyPatchToYArray(this.yElements, n, r);
483
+ }, this), this.lastSnapshot = this.cloneSnapshot(r);
484
+ } finally {
485
+ this.isApplyingLocal = !1;
486
+ }
487
+ }
488
+ }
489
+ applyPatchToYArray(e, r, n) {
490
+ for (const s of r) {
491
+ const i = this.getTopLevelIndex(s.path);
492
+ if (i !== null) {
493
+ if (s.op === "remove") {
494
+ i < e.length && e.delete(i, 1);
495
+ continue;
496
+ }
497
+ if (s.op === "add" || s.op === "replace") {
498
+ const a = this.getRootValueFromOperation(s, n);
499
+ if (!a || Array.isArray(a))
500
+ continue;
501
+ const u = this.jsonToYMap(a);
502
+ s.op === "add" ? e.insert(i, [u]) : (i < e.length && e.delete(i, 1), e.insert(i, [u]));
503
+ }
504
+ }
505
+ }
506
+ }
507
+ getTopLevelIndex(e) {
508
+ const r = e.split("/")[1];
509
+ if (!r) return null;
510
+ const n = Number(r);
511
+ return Number.isInteger(n) ? n : null;
512
+ }
513
+ getRootValueFromOperation(e, r) {
514
+ if (e.path.split("/").length <= 2) {
515
+ const s = e.value;
516
+ if (s && typeof s == "object" && !Array.isArray(s))
517
+ return s;
518
+ }
519
+ const n = this.getTopLevelIndex(e.path);
520
+ return n !== null && r[n] && typeof r[n] == "object" ? r[n] : null;
521
+ }
522
+ cloneSnapshot(e) {
523
+ return JSON.parse(JSON.stringify(e));
524
+ }
525
+ /** 将普通 JSON 对象转换为 Y.Map(递归处理嵌套数组) */
526
+ jsonToYMap(e) {
527
+ const r = new D.Map();
528
+ for (const [n, s] of Object.entries(e))
529
+ if (s != null)
530
+ if (fe.has(n) && Array.isArray(s)) {
531
+ const i = new D.Array(), a = s.map((u) => this.jsonToYMap(u));
532
+ i.insert(0, a), r.set(n, i);
533
+ } else
534
+ r.set(n, s);
535
+ return r;
536
+ }
537
+ }
538
+ const de = {
539
+ showLabel: !0,
540
+ labelDuration: 3e3,
541
+ enableBlink: !0,
542
+ expireTime: 3e4
543
+ };
544
+ class ve {
545
+ constructor(e = {}) {
546
+ d(this, "awareness", null);
547
+ d(this, "container", null);
548
+ d(this, "config");
549
+ d(this, "positionCalculator", null);
550
+ d(this, "cursors", /* @__PURE__ */ new Map());
551
+ d(this, "elements", /* @__PURE__ */ new Map());
552
+ d(this, "styleElement", null);
553
+ d(this, "cleanupTimer", null);
554
+ d(this, "awarenessHandler", null);
555
+ this.config = { ...de, ...e };
556
+ }
557
+ /**
558
+ * 绑定 Awareness 实例和当前用户信息
559
+ */
560
+ bindAwareness(e, r) {
561
+ this.awareness = e, e.setLocalStateField("user", {
562
+ userId: r.userId,
563
+ userName: r.userName,
564
+ color: r.color
565
+ }), this.awarenessHandler = ({ added: n, updated: s, removed: i }) => {
566
+ const a = [...n, ...s];
567
+ for (const u of a) {
568
+ if (u === this.awareness.clientID) continue;
569
+ const c = this.awareness.getStates().get(u);
570
+ if (!(c != null && c.user) || !(c != null && c.cursor)) continue;
571
+ const o = c.user, l = c.cursor, f = {
572
+ userId: o.userId,
573
+ userName: o.userName,
574
+ color: o.color,
575
+ position: l,
576
+ lastUpdate: Date.now()
577
+ };
578
+ this.cursors.set(o.userId, f), this.renderCursor(f);
579
+ }
580
+ if (i.length > 0) {
581
+ const u = this.awareness.getStates();
582
+ this.cleanupRemovedClients(u);
583
+ }
584
+ }, e.on("change", this.awarenessHandler);
585
+ }
586
+ /**
587
+ * 更新本地光标位置(写入 Awareness,自动广播到其他客户端)
588
+ */
589
+ setLocalCursor(e) {
590
+ var r;
591
+ (r = this.awareness) == null || r.setLocalStateField("cursor", e);
592
+ }
593
+ /**
594
+ * 初始化 DOM 渲染
595
+ */
596
+ initializeCursorRendering(e, r) {
597
+ this.container = e, this.positionCalculator = r, this.injectStyles(), this.startCleanupTimer();
598
+ }
599
+ /**
600
+ * 刷新所有光标位置(文档内容变化后调用)
601
+ */
602
+ refreshAllCursors() {
603
+ this.cursors.forEach((e) => this.renderCursor(e));
604
+ }
605
+ /**
606
+ * 获取所有远程光标
607
+ */
608
+ getAllCursors() {
609
+ return Array.from(this.cursors.values());
610
+ }
611
+ /**
612
+ * 销毁
613
+ */
614
+ destroy() {
615
+ this.awarenessHandler && this.awareness && (this.awareness.off("change", this.awarenessHandler), this.awarenessHandler = null), this.stopCleanupTimer(), this.clearAllElements(), this.removeStyles(), this.container = null, this.positionCalculator = null, this.awareness = null;
616
+ }
617
+ // ---- 内部渲染 ----
618
+ renderCursor(e) {
619
+ if (!this.container || !this.positionCalculator) return;
620
+ const r = this.positionCalculator(e.position.index);
621
+ if (!r) {
622
+ const s = this.elements.get(e.userId);
623
+ s && (s.container.style.display = "none");
624
+ return;
625
+ }
626
+ let n = this.elements.get(e.userId);
627
+ n || (n = this.createCursorElement(e), this.elements.set(e.userId, n)), n.container.style.left = `${r.x}px`, n.container.style.top = `${r.y}px`, n.container.style.display = "block", n.cursor.style.height = `${r.height}px`, n.cursor.style.backgroundColor = e.color, n.label.textContent = e.userName, n.label.style.backgroundColor = e.color, this.config.showLabel && this.showLabel(n);
628
+ }
629
+ createCursorElement(e) {
630
+ const r = document.createElement("div");
631
+ r.className = "remote-cursor-container", r.dataset.userId = e.userId;
632
+ const n = document.createElement("div");
633
+ n.className = "remote-cursor-line", this.config.enableBlink && n.classList.add("remote-cursor-blink");
634
+ const s = document.createElement("div");
635
+ return s.className = "remote-cursor-label", s.textContent = e.userName, r.appendChild(n), r.appendChild(s), this.container.appendChild(r), { container: r, cursor: n, label: s, labelTimer: null };
636
+ }
637
+ showLabel(e) {
638
+ e.label.style.opacity = "1", e.labelTimer && (clearTimeout(e.labelTimer), e.labelTimer = null), this.config.labelDuration > 0 && (e.labelTimer = setTimeout(() => {
639
+ e.label.style.opacity = "0", e.labelTimer = null;
640
+ }, this.config.labelDuration));
641
+ }
642
+ clearAllElements() {
643
+ this.elements.forEach((e) => {
644
+ e.labelTimer && clearTimeout(e.labelTimer), e.container.remove();
645
+ }), this.elements.clear(), this.cursors.clear();
646
+ }
647
+ /** 移除已经不在 awareness 中的客户端光标 */
648
+ cleanupRemovedClients(e) {
649
+ const r = /* @__PURE__ */ new Set();
650
+ e.forEach((s, i) => {
651
+ if (i === this.awareness.clientID) return;
652
+ const a = s.user;
653
+ a != null && a.userId && r.add(a.userId);
654
+ });
655
+ const n = [];
656
+ this.cursors.forEach((s, i) => {
657
+ r.has(i) || n.push(i);
658
+ });
659
+ for (const s of n)
660
+ this.removeCursor(s);
661
+ }
662
+ removeCursor(e) {
663
+ this.cursors.delete(e);
664
+ const r = this.elements.get(e);
665
+ r && (r.labelTimer && clearTimeout(r.labelTimer), r.container.remove(), this.elements.delete(e));
666
+ }
667
+ // ---- 过期清理 ----
668
+ startCleanupTimer() {
669
+ this.cleanupTimer = setInterval(() => {
670
+ const e = Date.now();
671
+ this.cursors.forEach((r, n) => {
672
+ e - r.lastUpdate > this.config.expireTime && this.removeCursor(n);
673
+ });
674
+ }, 5e3);
675
+ }
676
+ stopCleanupTimer() {
677
+ this.cleanupTimer && (clearInterval(this.cleanupTimer), this.cleanupTimer = null);
678
+ }
679
+ // ---- 样式注入 ----
680
+ injectStyles() {
681
+ this.styleElement || (this.styleElement = document.createElement("style"), this.styleElement.textContent = `
682
+ .remote-cursor-container {
683
+ position: absolute;
684
+ pointer-events: none;
685
+ z-index: 1000;
686
+ }
687
+ .remote-cursor-line {
688
+ width: 2px;
689
+ min-height: 16px;
690
+ border-radius: 1px;
691
+ }
692
+ .remote-cursor-blink {
693
+ animation: remote-cursor-blink 1s infinite;
694
+ }
695
+ @keyframes remote-cursor-blink {
696
+ 0%, 50% { opacity: 1; }
697
+ 51%, 100% { opacity: 0; }
698
+ }
699
+ .remote-cursor-label {
700
+ position: absolute;
701
+ top: -20px;
702
+ left: 0;
703
+ padding: 2px 6px;
704
+ border-radius: 3px;
705
+ color: white;
706
+ font-size: 12px;
707
+ white-space: nowrap;
708
+ transition: opacity 0.3s ease;
709
+ opacity: 0;
710
+ }
711
+ .remote-cursor-selection {
712
+ position: absolute;
713
+ opacity: 0.3;
714
+ pointer-events: none;
715
+ }
716
+ `, document.head.appendChild(this.styleElement));
717
+ }
718
+ removeStyles() {
719
+ this.styleElement && (this.styleElement.remove(), this.styleElement = null);
720
+ }
721
+ }
722
+ function ge(t) {
723
+ return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t;
724
+ }
725
+ var Q = { exports: {} };
726
+ (function(t) {
727
+ var e = Object.prototype.hasOwnProperty, r = "~";
728
+ function n() {
729
+ }
730
+ Object.create && (n.prototype = /* @__PURE__ */ Object.create(null), new n().__proto__ || (r = !1));
731
+ function s(c, o, l) {
732
+ this.fn = c, this.context = o, this.once = l || !1;
733
+ }
734
+ function i(c, o, l, f, g) {
735
+ if (typeof l != "function")
736
+ throw new TypeError("The listener must be a function");
737
+ var p = new s(l, f || c, g), v = r ? r + o : o;
738
+ return c._events[v] ? c._events[v].fn ? c._events[v] = [c._events[v], p] : c._events[v].push(p) : (c._events[v] = p, c._eventsCount++), c;
739
+ }
740
+ function a(c, o) {
741
+ --c._eventsCount === 0 ? c._events = new n() : delete c._events[o];
742
+ }
743
+ function u() {
744
+ this._events = new n(), this._eventsCount = 0;
745
+ }
746
+ u.prototype.eventNames = function() {
747
+ var o = [], l, f;
748
+ if (this._eventsCount === 0) return o;
749
+ for (f in l = this._events)
750
+ e.call(l, f) && o.push(r ? f.slice(1) : f);
751
+ return Object.getOwnPropertySymbols ? o.concat(Object.getOwnPropertySymbols(l)) : o;
752
+ }, u.prototype.listeners = function(o) {
753
+ var l = r ? r + o : o, f = this._events[l];
754
+ if (!f) return [];
755
+ if (f.fn) return [f.fn];
756
+ for (var g = 0, p = f.length, v = new Array(p); g < p; g++)
757
+ v[g] = f[g].fn;
758
+ return v;
759
+ }, u.prototype.listenerCount = function(o) {
760
+ var l = r ? r + o : o, f = this._events[l];
761
+ return f ? f.fn ? 1 : f.length : 0;
762
+ }, u.prototype.emit = function(o, l, f, g, p, v) {
763
+ var E = r ? r + o : o;
764
+ if (!this._events[E]) return !1;
765
+ var h = this._events[E], _ = arguments.length, T, y;
766
+ if (h.fn) {
767
+ switch (h.once && this.removeListener(o, h.fn, void 0, !0), _) {
768
+ case 1:
769
+ return h.fn.call(h.context), !0;
770
+ case 2:
771
+ return h.fn.call(h.context, l), !0;
772
+ case 3:
773
+ return h.fn.call(h.context, l, f), !0;
774
+ case 4:
775
+ return h.fn.call(h.context, l, f, g), !0;
776
+ case 5:
777
+ return h.fn.call(h.context, l, f, g, p), !0;
778
+ case 6:
779
+ return h.fn.call(h.context, l, f, g, p, v), !0;
780
+ }
781
+ for (y = 1, T = new Array(_ - 1); y < _; y++)
782
+ T[y - 1] = arguments[y];
783
+ h.fn.apply(h.context, T);
784
+ } else {
785
+ var K = h.length, b;
786
+ for (y = 0; y < K; y++)
787
+ switch (h[y].once && this.removeListener(o, h[y].fn, void 0, !0), _) {
788
+ case 1:
789
+ h[y].fn.call(h[y].context);
790
+ break;
791
+ case 2:
792
+ h[y].fn.call(h[y].context, l);
793
+ break;
794
+ case 3:
795
+ h[y].fn.call(h[y].context, l, f);
796
+ break;
797
+ case 4:
798
+ h[y].fn.call(h[y].context, l, f, g);
799
+ break;
800
+ default:
801
+ if (!T) for (b = 1, T = new Array(_ - 1); b < _; b++)
802
+ T[b - 1] = arguments[b];
803
+ h[y].fn.apply(h[y].context, T);
804
+ }
805
+ }
806
+ return !0;
807
+ }, u.prototype.on = function(o, l, f) {
808
+ return i(this, o, l, f, !1);
809
+ }, u.prototype.once = function(o, l, f) {
810
+ return i(this, o, l, f, !0);
811
+ }, u.prototype.removeListener = function(o, l, f, g) {
812
+ var p = r ? r + o : o;
813
+ if (!this._events[p]) return this;
814
+ if (!l)
815
+ return a(this, p), this;
816
+ var v = this._events[p];
817
+ if (v.fn)
818
+ v.fn === l && (!g || v.once) && (!f || v.context === f) && a(this, p);
819
+ else {
820
+ for (var E = 0, h = [], _ = v.length; E < _; E++)
821
+ (v[E].fn !== l || g && !v[E].once || f && v[E].context !== f) && h.push(v[E]);
822
+ h.length ? this._events[p] = h.length === 1 ? h[0] : h : a(this, p);
823
+ }
824
+ return this;
825
+ }, u.prototype.removeAllListeners = function(o) {
826
+ var l;
827
+ return o ? (l = r ? r + o : o, this._events[l] && a(this, l)) : (this._events = new n(), this._eventsCount = 0), this;
828
+ }, u.prototype.off = u.prototype.removeListener, u.prototype.addListener = u.prototype.on, u.prefixed = r, u.EventEmitter = u, t.exports = u;
829
+ })(Q);
830
+ var me = Q.exports;
831
+ const ye = /* @__PURE__ */ ge(me);
832
+ function we(t, e, r) {
833
+ return typeof t.select == "function" ? t.select(e).subscribe(r) : typeof t.on == "function" ? (t.on(e, r), {
834
+ unsubscribe: () => {
835
+ typeof t.off == "function" && t.off(e, r);
836
+ }
837
+ }) : { unsubscribe: () => {
838
+ } };
839
+ }
840
+ class Te {
841
+ constructor(e) {
842
+ d(this, "editor", null);
843
+ d(this, "config");
844
+ d(this, "doc", null);
845
+ d(this, "provider", null);
846
+ d(this, "binding", null);
847
+ d(this, "cursorManager");
848
+ d(this, "connectionState", C.DISCONNECTED);
849
+ d(this, "syncState", R.SYNCING);
850
+ /** 光标节流 */
851
+ d(this, "cursorThrottleTimer", null);
852
+ /** 编辑器事件引用 */
853
+ d(this, "rangeChangeHandler", null);
854
+ d(this, "rangeChangeSubscription", null);
855
+ d(this, "eventEmitter", new ye());
856
+ /** 已知在线用户(从 Awareness 维护) */
857
+ d(this, "onlineUsers", /* @__PURE__ */ new Map());
858
+ d(this, "_positionListDirty", !0);
859
+ d(this, "_cachedPositionList", null);
860
+ this.config = {
861
+ enableRemoteCursors: !0,
862
+ cursorThrottleMs: 100,
863
+ ...e
864
+ }, this.cursorManager = new ve();
865
+ }
866
+ // ==================== 公开 API ====================
867
+ install(e) {
868
+ this.editor = e;
869
+ }
870
+ uninstall() {
871
+ var e;
872
+ this.disconnect(), (e = this.rangeChangeSubscription) == null || e.unsubscribe(), this.rangeChangeSubscription = null, this.rangeChangeHandler = null, this.cursorManager.destroy(), this.editor = null;
873
+ }
874
+ async connect() {
875
+ if (!this.editor) throw new Error("Plugin not installed");
876
+ if (this.provider) return;
877
+ const { collaboration: e } = this.config;
878
+ this.doc = new D.Doc();
879
+ const r = e.token ?? JSON.stringify({
880
+ userId: e.user.userId,
881
+ userName: e.user.userName,
882
+ color: e.user.color
883
+ });
884
+ this.setConnectionState(C.CONNECTING), this.provider = new X({
885
+ url: e.serverUrl,
886
+ name: e.docId,
887
+ document: this.doc,
888
+ token: r,
889
+ // 连接事件
890
+ onConnect: () => {
891
+ this.setConnectionState(C.CONNECTED);
892
+ },
893
+ onDisconnect: () => {
894
+ this.setConnectionState(C.DISCONNECTED);
895
+ },
896
+ onSynced: ({ state: n }) => {
897
+ n && (this.setSyncState(R.SYNCED), !this.binding && this.editor && this.doc && (this.binding = new pe(this.doc, this.editor)));
898
+ },
899
+ onAuthenticationFailed: ({ reason: n }) => {
900
+ this.emitEvent("error", { code: "AUTH_FAILED", message: n });
901
+ }
902
+ }), this.config.enableRemoteCursors && (this.cursorManager.bindAwareness(this.provider.awareness, e.user), this.setupAwarenessUserTracking()), this.setupCursorSync();
903
+ }
904
+ disconnect() {
905
+ this.binding && (this.binding.destroy(), this.binding = null), this.cursorThrottleTimer && (clearTimeout(this.cursorThrottleTimer), this.cursorThrottleTimer = null), this.provider && (this.provider.destroy(), this.provider = null), this.doc && (this.doc.destroy(), this.doc = null), this.onlineUsers.clear(), this.setConnectionState(C.DISCONNECTED);
906
+ }
907
+ getConnectionState() {
908
+ return this.connectionState;
909
+ }
910
+ getSyncState() {
911
+ return this.syncState;
912
+ }
913
+ getOnlineUsers() {
914
+ return Array.from(this.onlineUsers.values());
915
+ }
916
+ getRemoteCursors() {
917
+ return this.cursorManager.getAllCursors();
918
+ }
919
+ initializeCursors(e, r) {
920
+ this.config.enableRemoteCursors && this.cursorManager.initializeCursorRendering(e, r);
921
+ }
922
+ markPositionListDirty() {
923
+ this._positionListDirty = !0;
924
+ }
925
+ initializeCursorsWithEditor(e) {
926
+ if (!this.config.enableRemoteCursors || !this.editor) return;
927
+ const r = this.editor, n = (s) => {
928
+ var v, E, h, _;
929
+ if ((this._positionListDirty || !this._cachedPositionList) && (this._cachedPositionList = ((E = (v = r.command).getPositionList) == null ? void 0 : E.call(v)) || null, this._positionListDirty = !1), !this._cachedPositionList || s < 0 || s >= this._cachedPositionList.length) return null;
930
+ const i = this._cachedPositionList[s];
931
+ if (!(i != null && i.coordinate)) return null;
932
+ const a = i.pageNo ?? 0, c = e.querySelectorAll("canvas[data-index]")[a];
933
+ if (!c) return null;
934
+ const o = c.getBoundingClientRect(), l = e.getBoundingClientRect(), f = o.left - l.left + e.scrollLeft + (((h = i.coordinate.leftTop) == null ? void 0 : h[0]) || 0), g = o.top - l.top + e.scrollTop + (((_ = i.coordinate.leftTop) == null ? void 0 : _[1]) || 0), p = i.lineHeight || 16;
935
+ return { x: f, y: g, height: p };
936
+ };
937
+ this.cursorManager.initializeCursorRendering(e, n);
938
+ }
939
+ refreshCursors() {
940
+ this.cursorManager.refreshAllCursors();
941
+ }
942
+ on(e, r) {
943
+ return this.addEventListener(e, r);
944
+ }
945
+ addEventListener(e, r) {
946
+ return this.eventEmitter.on(e, r), () => {
947
+ this.eventEmitter.off(e, r);
948
+ };
949
+ }
950
+ // ==================== 内部 ====================
951
+ /** 监听 Awareness 变化维护在线用户列表 */
952
+ setupAwarenessUserTracking() {
953
+ const e = this.provider.awareness, r = this.config.collaboration.user;
954
+ this.onlineUsers.set(r.userId, r), this.emitEvent("usersChange", this.getOnlineUsers());
955
+ const n = ({ added: s, updated: i, removed: a }) => {
956
+ let u = !1;
957
+ for (const c of [...s, ...i]) {
958
+ if (c === e.clientID) continue;
959
+ const o = e.getStates().get(c), l = o == null ? void 0 : o.user;
960
+ l != null && l.userId && !this.onlineUsers.has(l.userId) && (this.onlineUsers.set(l.userId, l), this.emitEvent("userJoin", l), u = !0);
961
+ }
962
+ if (a.length > 0) {
963
+ const c = /* @__PURE__ */ new Set();
964
+ c.add(r.userId), e.getStates().forEach((o, l) => {
965
+ if (l === e.clientID) return;
966
+ const f = o.user;
967
+ f != null && f.userId && c.add(f.userId);
968
+ }), this.onlineUsers.forEach((o, l) => {
969
+ c.has(l) || (this.onlineUsers.delete(l), this.emitEvent("userLeave", l), u = !0);
970
+ });
971
+ }
972
+ u && this.emitEvent("usersChange", this.getOnlineUsers());
973
+ };
974
+ e.on("change", n);
975
+ }
976
+ /** 编辑器光标 → Awareness */
977
+ setupCursorSync() {
978
+ this.editor && (this.rangeChangeHandler = () => {
979
+ this.cursorThrottleTimer || (this.cursorThrottleTimer = setTimeout(() => {
980
+ var n;
981
+ this.cursorThrottleTimer = null;
982
+ const e = (n = this.editor) == null ? void 0 : n.command.getRange();
983
+ if (!e) return;
984
+ const r = {
985
+ index: e.startIndex,
986
+ endIndex: e.startIndex !== e.endIndex ? e.endIndex : void 0
987
+ };
988
+ this.cursorManager.setLocalCursor(r);
989
+ }, this.config.cursorThrottleMs));
990
+ }, this.rangeChangeSubscription = we(
991
+ this.editor.eventBus,
992
+ "rangeStyleChange",
993
+ this.rangeChangeHandler
994
+ ));
995
+ }
996
+ setConnectionState(e) {
997
+ this.connectionState !== e && (this.connectionState = e, this.emitEvent("connectionChange", e));
998
+ }
999
+ setSyncState(e) {
1000
+ this.syncState !== e && (this.syncState = e, this.emitEvent("syncStateChange", e));
1001
+ }
1002
+ emitEvent(e, ...r) {
1003
+ this.eventEmitter.listeners(e).forEach((s) => {
1004
+ try {
1005
+ s(...r);
1006
+ } catch (i) {
1007
+ console.error(`[CollaborationPlugin] Error in ${String(e)} handler:`, i);
1008
+ }
1009
+ });
1010
+ }
1011
+ }
1012
+ export {
1013
+ ve as AwarenessCursorManager,
1014
+ Te as CollaborationPlugin,
1015
+ C as ConnectionState,
1016
+ R as SyncState,
1017
+ pe as YjsBinding
1018
+ };
1019
+ //# sourceMappingURL=docx-editor-collaboration.js.map