@web-ppt/collab 0.5.0-beta.2 → 0.5.0-beta.7
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/CHANGELOG.md +171 -0
- package/README.md +12 -0
- package/dist/binding-DoPW07so.js +1060 -0
- package/dist/binding.d.ts +5 -0
- package/dist/collab.js +9 -878
- package/dist/evaluate.d.ts +3 -1
- package/dist/extension-addresses.d.ts +4 -0
- package/dist/message.d.ts +2 -0
- package/dist/migration/copies.d.ts +9 -0
- package/dist/migration/evaluate.d.ts +6 -0
- package/dist/migration/evidence.d.ts +2 -0
- package/dist/migration/index.d.ts +5 -0
- package/dist/migration/receipt-registers.d.ts +4 -0
- package/dist/migration/resolve.d.ts +4 -0
- package/dist/migration.js +412 -0
- package/dist/section-conflict.d.ts +3 -0
- package/dist/section-order.d.ts +4 -0
- package/dist/slide-conflict.d.ts +2 -0
- package/dist/state.d.ts +10 -5
- package/dist/table-conflict.d.ts +9 -0
- package/dist/types.d.ts +11 -0
- package/package.json +24 -5
|
@@ -0,0 +1,1060 @@
|
|
|
1
|
+
import { MAX_COLLABORATION_VERSION as z, MAX_PATCHES_PER_TRANSACTION as xe, assertEditIdentityWatermark as Re, sectionOfSlide as je, isExtensionMigrationPatch as ge, tableGridIdentities as Le, EXTENSION_ADDRESSES as ke, canonicalExtensionPath as Pe, isExtensionAddressPatch as B, stageExternalPatches as N, extensionMigrationPatches as Ae, canonicalExtensionPatch as qe, configureCollaborationIdentity as Ne } from "@web-ppt/edit-core";
|
|
2
|
+
function D(e, t) {
|
|
3
|
+
return e.clock !== t.clock ? e.clock < t.clock ? -1 : 1 : e.replicaId === t.replicaId ? 0 : e.replicaId < t.replicaId ? -1 : 1;
|
|
4
|
+
}
|
|
5
|
+
const te = (e) => typeof e == "number" && Number.isSafeInteger(e) && e > 0, re = (e) => typeof e == "string" && e.length >= 1 && e.length <= 128 && !/[\0-\x1f\x7f]/.test(e);
|
|
6
|
+
function ve(e) {
|
|
7
|
+
const t = e, r = t == null ? void 0 : t.stamp;
|
|
8
|
+
if (!t || typeof t != "object" || t.version !== 1 || !re(t.documentId) || !re(t.replicaId) || !te(t.sequence) || t.sequence > z || !r || !te(r.clock) || r.clock > z || r.replicaId !== t.replicaId || !Array.isArray(t.patches) || !t.patches.length || t.patches.length > xe || t.patches.some((n) => !n || typeof n != "object" || !Array.isArray(n.path) || !n.path.length || typeof n.op != "string" || typeof n.origin != "string") || typeof t.label != "string" || !Number.isFinite(t.time))
|
|
9
|
+
throw new Error("协同消息结构无效");
|
|
10
|
+
try {
|
|
11
|
+
Re(t.identity);
|
|
12
|
+
} catch {
|
|
13
|
+
throw new Error("协同消息的身份水位或身份分配命名空间无效");
|
|
14
|
+
}
|
|
15
|
+
const s = t.identity.allocation;
|
|
16
|
+
if (!s || s.replicaId !== t.replicaId || s.clock !== r.clock || s.sequence !== t.sequence)
|
|
17
|
+
throw new Error("协同消息的身份版本与消息头不一致");
|
|
18
|
+
}
|
|
19
|
+
const X = (e) => JSON.stringify(e.path), $e = (e) => `${e.replicaId}\0${e.sequence}`, ye = 4096, we = 1e4;
|
|
20
|
+
function _e(e = []) {
|
|
21
|
+
return new Map(e.map((t) => [t.replicaId, {
|
|
22
|
+
contiguous: t.contiguous,
|
|
23
|
+
sparse: new Set(t.sparse)
|
|
24
|
+
}]));
|
|
25
|
+
}
|
|
26
|
+
function ze(e) {
|
|
27
|
+
return new Map([...e].map(([t, r]) => [t, {
|
|
28
|
+
contiguous: r.contiguous,
|
|
29
|
+
sparse: new Set(r.sparse)
|
|
30
|
+
}]));
|
|
31
|
+
}
|
|
32
|
+
function De(e) {
|
|
33
|
+
return [...e].map(([t, r]) => ({
|
|
34
|
+
replicaId: t,
|
|
35
|
+
contiguous: r.contiguous,
|
|
36
|
+
sparse: [...r.sparse].sort((s, n) => s - n)
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
function Te(e, t) {
|
|
40
|
+
const r = e.get(t.replicaId);
|
|
41
|
+
return !!r && (t.sequence <= r.contiguous || r.sparse.has(t.sequence));
|
|
42
|
+
}
|
|
43
|
+
function ne(e, t) {
|
|
44
|
+
var r;
|
|
45
|
+
return t.sequence > (((r = e.get(t.replicaId)) == null ? void 0 : r.contiguous) ?? 0) + 1;
|
|
46
|
+
}
|
|
47
|
+
function se(e, t) {
|
|
48
|
+
let r = e.get(t.replicaId);
|
|
49
|
+
if (!r) {
|
|
50
|
+
if (e.size >= ye) throw new Error("协同消息副本数超过安全上限");
|
|
51
|
+
r = { contiguous: 0, sparse: /* @__PURE__ */ new Set() }, e.set(t.replicaId, r);
|
|
52
|
+
}
|
|
53
|
+
if (t.sequence <= r.contiguous || r.sparse.has(t.sequence)) return;
|
|
54
|
+
if (t.sequence === r.contiguous + 1) {
|
|
55
|
+
for (r.contiguous++; r.sparse.delete(r.contiguous + 1); ) r.contiguous++;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if ([...e.values()].reduce((n, c) => n + c.sparse.size, 0) >= we) throw new Error("协同消息乱序缺口超过安全上限");
|
|
59
|
+
r.sparse.add(t.sequence);
|
|
60
|
+
}
|
|
61
|
+
const K = (e) => typeof e == "number" && Number.isSafeInteger(e) && e >= 0 && e <= z, oe = (e) => Array.isArray(e) && e.every((t) => typeof t == "string" && !!t) && new Set(e).size === e.length;
|
|
62
|
+
function Q(e, t) {
|
|
63
|
+
const r = e;
|
|
64
|
+
if (!r || typeof r != "object" || !Number.isSafeInteger(r.clock) || r.clock <= 0 || r.clock > z || typeof r.replicaId != "string" || !r.replicaId)
|
|
65
|
+
throw new Error(`${t} 的 LWW 时间戳无效`);
|
|
66
|
+
}
|
|
67
|
+
function _(e, t, r) {
|
|
68
|
+
if (!Array.isArray(e) || e.length > 1e5) throw new Error(`${t} 无效`);
|
|
69
|
+
const s = /* @__PURE__ */ new Set();
|
|
70
|
+
e.forEach((n, c) => {
|
|
71
|
+
if (!Array.isArray(n) || n.length !== 2 || typeof n[0] != "string" || !n[0] || s.has(n[0])) throw new Error(`${t} 的键无效`);
|
|
72
|
+
s.add(n[0]), r(n[1], `${t}[${c}]`);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function Je(e, t) {
|
|
76
|
+
const r = e;
|
|
77
|
+
if (!r || typeof r != "object" || r.kind !== "field" && r.kind !== "hierarchy")
|
|
78
|
+
throw new Error(`${t} 的 register 无效`);
|
|
79
|
+
Q(r.stamp, t);
|
|
80
|
+
}
|
|
81
|
+
function ce(e, t) {
|
|
82
|
+
const r = e;
|
|
83
|
+
if (!r || typeof r != "object" || r.state !== "present" && r.state !== "removed")
|
|
84
|
+
throw new Error(`${t} 的生命周期无效`);
|
|
85
|
+
Q(r.stamp, t);
|
|
86
|
+
}
|
|
87
|
+
function ie(e, t) {
|
|
88
|
+
const r = e;
|
|
89
|
+
if (!r || typeof r != "object" || r.after !== null && (typeof r.after != "string" || !r.after) || typeof r.ordinal != "number" || !Number.isSafeInteger(r.ordinal) || r.ordinal < 0)
|
|
90
|
+
throw new Error(`${t} 的页序意图无效`);
|
|
91
|
+
Q(r.stamp, t);
|
|
92
|
+
}
|
|
93
|
+
function We(e) {
|
|
94
|
+
if (!Array.isArray(e) || e.length > ye)
|
|
95
|
+
throw new Error("协同 checkpoint seen 无效");
|
|
96
|
+
const t = /* @__PURE__ */ new Set();
|
|
97
|
+
let r = 0;
|
|
98
|
+
for (const s of e) {
|
|
99
|
+
const n = s;
|
|
100
|
+
if (!n || typeof n != "object" || typeof n.replicaId != "string" || !n.replicaId || n.replicaId.length > 128 || /[\0-\x1f\x7f]/.test(n.replicaId) || t.has(n.replicaId) || !K(n.contiguous) || !Array.isArray(n.sparse)) throw new Error("协同 checkpoint seen 无效");
|
|
101
|
+
t.add(n.replicaId);
|
|
102
|
+
let c = n.contiguous;
|
|
103
|
+
for (const o of n.sparse) {
|
|
104
|
+
if (!Number.isSafeInteger(o) || o <= c || o > z) throw new Error("协同 checkpoint seen 无效");
|
|
105
|
+
c = o, r++;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (r > we) throw new Error("协同 checkpoint seen 无效");
|
|
109
|
+
}
|
|
110
|
+
function Xe(e, t, r) {
|
|
111
|
+
const s = e;
|
|
112
|
+
if (!s || typeof s != "object" || s.version !== 1 || s.documentId !== t.documentId || s.replicaId !== t.replicaId || s.replicaSlot !== t.replicaSlot || !K(s.clock) || !K(s.sequence) || s.clock !== r.clock || s.sequence !== r.sequence || !oe(s.baseSlideOrder) || s.baseSectionOrder !== void 0 && !oe(s.baseSectionOrder) || !Array.isArray(s.deferred) || s.deferred.length > 1e4)
|
|
113
|
+
throw new Error("协同 checkpoint 与恢复文档不匹配");
|
|
114
|
+
_(s.registers, "协同 checkpoint registers", Je), _(s.elementLifecycles, "协同 checkpoint elementLifecycles", ce), _(s.slideLifecycles, "协同 checkpoint slideLifecycles", ce), _(s.slideMoves, "协同 checkpoint slideMoves", ie), s.sectionMoves !== void 0 && _(s.sectionMoves, "sectionMoves", ie), We(s.seen), s.deferred.forEach((n, c) => {
|
|
115
|
+
if (!n || typeof n != "object" || !Number.isSafeInteger(n.ordinal) || n.ordinal < 0) throw new Error(`协同 checkpoint deferred[${c}] 无效`);
|
|
116
|
+
if (ve(n.message), n.message.documentId !== t.documentId || n.ordinal >= n.message.patches.length || JSON.stringify(n.patch) !== JSON.stringify(n.message.patches[n.ordinal]))
|
|
117
|
+
throw new Error(`协同 checkpoint deferred[${c}] 与消息不匹配`);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
const le = (e) => e === "__proto__" || e === "prototype" || e === "constructor";
|
|
121
|
+
function Fe(e) {
|
|
122
|
+
const t = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), s = e.map((c) => structuredClone(c));
|
|
123
|
+
if (e.forEach((c, o) => {
|
|
124
|
+
let i = null;
|
|
125
|
+
(c.op === "insert" && c.path.length === 2 && c.path[0] === "elements" || c.op === "set" && c.path.length === 3 && c.path[0] === "elements" && c.path[2] === "hierarchy") && (i = s[o].value.records);
|
|
126
|
+
for (const [l, u] of Object.entries(i ?? {}))
|
|
127
|
+
u && t.set(l, { index: o, record: u });
|
|
128
|
+
if (c.op === "insert" && c.path.length === 2 && c.path[0] === "slides") {
|
|
129
|
+
const l = s[o];
|
|
130
|
+
r.set(l.path[1], { index: o, record: l.value.slide });
|
|
131
|
+
for (const [u, y] of Object.entries(l.value.records))
|
|
132
|
+
t.set(u, { index: o, record: y });
|
|
133
|
+
}
|
|
134
|
+
}), !t.size && !r.size) return [...e];
|
|
135
|
+
const n = /* @__PURE__ */ new Set();
|
|
136
|
+
for (let c = 0; c < e.length; c++) {
|
|
137
|
+
const o = e[c];
|
|
138
|
+
if (o.path.length >= 3 && o.path[0] === "slides" && (o.op === "set" || o.op === "del")) {
|
|
139
|
+
const u = r.get(o.path[1]);
|
|
140
|
+
if (!u || u.index >= c) continue;
|
|
141
|
+
const y = o.path.slice(2);
|
|
142
|
+
if (y.some((b) => typeof b != "string" || le(b))) continue;
|
|
143
|
+
let f = u.record, d = !0;
|
|
144
|
+
for (const b of y.slice(0, -1)) {
|
|
145
|
+
const p = f[b];
|
|
146
|
+
if (!p || typeof p != "object" || Array.isArray(p)) {
|
|
147
|
+
d = !1;
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
f = p;
|
|
151
|
+
}
|
|
152
|
+
if (!d) continue;
|
|
153
|
+
const w = y[y.length - 1];
|
|
154
|
+
o.op === "set" ? f[w] = structuredClone(o.value) : delete f[w], n.add(c);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (o.path.length !== 4 || o.path[0] !== "elements" || o.path[2] !== "ovr" || o.op !== "set" && o.op !== "del" || le(o.path[3])) continue;
|
|
158
|
+
const i = t.get(o.path[1]);
|
|
159
|
+
if (!i || i.index >= c) continue;
|
|
160
|
+
const l = i.record.ovr;
|
|
161
|
+
o.op === "set" ? l[o.path[3]] = structuredClone(o.value) : delete l[o.path[3]], n.add(c);
|
|
162
|
+
}
|
|
163
|
+
return s.filter((c, o) => !n.has(o));
|
|
164
|
+
}
|
|
165
|
+
const He = ["x", "y", "w", "h", "rot", "flipH", "flipV"], Be = (e) => e.op === "set" && e.path.length === 3 && e.path[0] === "elements" && e.path[2] === "hierarchy" ? e.value.records : null;
|
|
166
|
+
function Ge(e, t, r) {
|
|
167
|
+
const s = t.path[1];
|
|
168
|
+
if (r.has(t.value.parent) || r.has(s) && t.value.records[s] !== null) return null;
|
|
169
|
+
const n = Object.keys(t.value.records).filter((l) => l !== s && r.has(l) && t.value.records[l] !== null);
|
|
170
|
+
if (!n.length) return t;
|
|
171
|
+
const c = structuredClone(t), o = c.value, i = new Set(n);
|
|
172
|
+
for (const l of n) {
|
|
173
|
+
const u = o.records[l], y = e.removedElements[l];
|
|
174
|
+
o.removed[l] = y ? structuredClone(y) : {
|
|
175
|
+
id: l,
|
|
176
|
+
parent: u.parent,
|
|
177
|
+
meta: structuredClone(u.meta),
|
|
178
|
+
...u.meta.origin ? { sourceSpids: [u.meta.origin.spid] } : {}
|
|
179
|
+
}, delete o.records[l], delete o.children[l];
|
|
180
|
+
}
|
|
181
|
+
o.affected = o.affected.filter((l) => !i.has(l));
|
|
182
|
+
for (const [l, u] of Object.entries(o.children))
|
|
183
|
+
o.children[l] = u.filter((y) => !i.has(y));
|
|
184
|
+
for (const l of Object.values(o.records))
|
|
185
|
+
l != null && l.children && (l.children = l.children.filter((u) => !i.has(u)));
|
|
186
|
+
return c;
|
|
187
|
+
}
|
|
188
|
+
function Ke(e, t) {
|
|
189
|
+
if (!t.size) return e;
|
|
190
|
+
const r = e.path[1];
|
|
191
|
+
if (e.value.records[r] === null) return e;
|
|
192
|
+
if (t.has(r)) return null;
|
|
193
|
+
const n = structuredClone(e), c = n.value, o = (c.children[r] ?? []).filter((l) => !t.has(l));
|
|
194
|
+
if (!o.length) return null;
|
|
195
|
+
for (const l of t)
|
|
196
|
+
l !== r && (delete c.records[l], delete c.children[l]);
|
|
197
|
+
c.children[r] = o;
|
|
198
|
+
const i = /* @__PURE__ */ new Set([r, ...o]);
|
|
199
|
+
return c.affected = c.affected.filter((l) => i.has(l)), n;
|
|
200
|
+
}
|
|
201
|
+
function V(e, t) {
|
|
202
|
+
var r, s;
|
|
203
|
+
return ((r = e.slides[t]) == null ? void 0 : r.children) ?? ((s = e.elements[t]) == null ? void 0 : s.children) ?? [];
|
|
204
|
+
}
|
|
205
|
+
function de(e) {
|
|
206
|
+
return e.order ?? e.z;
|
|
207
|
+
}
|
|
208
|
+
function ae(e, t, r) {
|
|
209
|
+
return [...new Set(e)].filter((s) => t[s] !== null && !!(t[s] ?? r.elements[s])).sort((s, n) => {
|
|
210
|
+
const c = t[s] ?? r.elements[s], o = t[n] ?? r.elements[n], i = de(c), l = de(o);
|
|
211
|
+
return (i < l ? -1 : i === l ? 0 : 1) || (s < n ? -1 : s === n ? 0 : 1);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function Ve(e, t, r, s) {
|
|
215
|
+
const n = structuredClone(e);
|
|
216
|
+
if (n.parent = t.parent, n.z = t.z, r(t.id, "order") && (t.order === void 0 ? delete n.order : n.order = t.order), t.meta.sourceParent === void 0 ? delete n.meta.sourceParent : n.meta.sourceParent = t.meta.sourceParent, s) for (const c of He)
|
|
217
|
+
r(t.id, c) && (Object.prototype.hasOwnProperty.call(t.ovr, c) ? n.ovr[c] = t.ovr[c] : delete n.ovr[c]);
|
|
218
|
+
return n;
|
|
219
|
+
}
|
|
220
|
+
function Ue(e, t, r) {
|
|
221
|
+
const s = e.elements[t];
|
|
222
|
+
if (!s) throw new Error(`协同层级闭包找不到元素:${t}`);
|
|
223
|
+
const n = /* @__PURE__ */ Object.create(null), c = (o) => {
|
|
224
|
+
if (!r.has(o)) return;
|
|
225
|
+
const i = e.elements[o];
|
|
226
|
+
if (!i) throw new Error(`协同层级闭包找不到后代:${o}`);
|
|
227
|
+
n[o] = {
|
|
228
|
+
...structuredClone(i),
|
|
229
|
+
...i.children ? { children: i.children.filter((l) => r.has(l)) } : {}
|
|
230
|
+
};
|
|
231
|
+
for (const l of i.children ?? []) c(l);
|
|
232
|
+
};
|
|
233
|
+
return c(t), { root: t, parent: s.parent, records: n };
|
|
234
|
+
}
|
|
235
|
+
function fe(e, t) {
|
|
236
|
+
const r = /* @__PURE__ */ new Set(), s = (n) => {
|
|
237
|
+
if (r.has(n)) return;
|
|
238
|
+
const c = e.elements[n];
|
|
239
|
+
if (!c) throw new Error(`协同层级闭包找不到元素:${n}`);
|
|
240
|
+
r.add(n);
|
|
241
|
+
for (const o of c.children ?? []) s(o);
|
|
242
|
+
};
|
|
243
|
+
return t.forEach(s), r;
|
|
244
|
+
}
|
|
245
|
+
function Qe(e, t, r) {
|
|
246
|
+
var p, E;
|
|
247
|
+
const s = structuredClone(t);
|
|
248
|
+
if (!e.slides[t.value.parent] && !e.elements[t.value.parent]) return s;
|
|
249
|
+
const n = s.value, c = t.path[1], i = n.records[c] === null, l = Object.entries(n.records).flatMap(([g, m]) => g !== c && m !== null ? [g] : []), u = new Set(l), y = /* @__PURE__ */ new Set();
|
|
250
|
+
if (i) {
|
|
251
|
+
const g = fe(e, l.filter((h) => !!e.elements[h]));
|
|
252
|
+
if (e.elements[c]) for (const h of fe(e, [c]))
|
|
253
|
+
h !== c && !g.has(h) && y.add(h);
|
|
254
|
+
const S = [...y].filter((h) => {
|
|
255
|
+
var I;
|
|
256
|
+
return !y.has(((I = e.elements[h]) == null ? void 0 : I.parent) ?? "");
|
|
257
|
+
});
|
|
258
|
+
for (const h of y)
|
|
259
|
+
n.records[h] = null, n.affected.push(h), delete n.children[h];
|
|
260
|
+
for (const h of S) {
|
|
261
|
+
const I = Ue(e, h, y), a = I.records[h];
|
|
262
|
+
if (a.meta.created) {
|
|
263
|
+
n.removed[h] = null;
|
|
264
|
+
for (const v of Object.values(I.records))
|
|
265
|
+
!v.meta.created && v.meta.sourceParent !== void 0 && (n.removed[v.id] = F(I, v));
|
|
266
|
+
} else n.removed[h] = F(I, a);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
for (const g of l) {
|
|
270
|
+
const m = e.elements[g], S = n.records[g];
|
|
271
|
+
m && S && (n.records[g] = Ve(m, S, r, i));
|
|
272
|
+
}
|
|
273
|
+
const f = /* @__PURE__ */ new Set();
|
|
274
|
+
for (const g of l) {
|
|
275
|
+
const m = (p = e.elements[g]) == null ? void 0 : p.parent;
|
|
276
|
+
if (m && m !== n.parent && m !== c) {
|
|
277
|
+
const S = e.elements[m], h = i ? c : n.parent;
|
|
278
|
+
(S == null ? void 0 : S.src.kind) === "group" && S.meta.created && S.parent === h && f.add(m);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
const d = /* @__PURE__ */ new Set();
|
|
282
|
+
for (const g of f) {
|
|
283
|
+
const m = e.elements[g], S = (m.children ?? []).filter((h) => !u.has(h) && !y.has(h));
|
|
284
|
+
n.affected.push(g), S.length ? (n.records[g] = { ...structuredClone(m), children: S }, n.children[g] = S) : (n.records[g] = null, n.removed[g] = null, delete n.children[g], d.add(g));
|
|
285
|
+
}
|
|
286
|
+
if (i) {
|
|
287
|
+
const g = (E = e.elements[c]) == null ? void 0 : E.parent, m = g ? e.elements[g] : void 0;
|
|
288
|
+
if ((m == null ? void 0 : m.src.kind) === "group" && g !== n.parent) {
|
|
289
|
+
const S = (m.children ?? []).filter((h) => h !== c);
|
|
290
|
+
n.affected.push(m.id), S.length || !m.meta.created ? (n.records[m.id] = { ...structuredClone(m), children: S }, n.children[m.id] = S) : (n.records[m.id] = null, n.removed[m.id] = null, delete n.children[m.id], d.add(m.id), m.parent !== n.parent && (n.children[m.parent] = V(e, m.parent).filter((h) => h !== m.id)));
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
const b = V(e, n.parent).filter((g) => !u.has(g) && g !== c && !d.has(g));
|
|
294
|
+
return i ? b.push(...l) : b.push(c), n.children[n.parent] = ae(b, n.records, e), i || (n.children[c] = ae(l, n.records, e)), n.affected = [...new Set(n.affected)], s;
|
|
295
|
+
}
|
|
296
|
+
function Ye(e, t) {
|
|
297
|
+
var c;
|
|
298
|
+
const r = (c = t.meta.origin) == null ? void 0 : c.part, s = [], n = (o) => {
|
|
299
|
+
const i = e.records[o];
|
|
300
|
+
if (!i) return;
|
|
301
|
+
const l = i.meta.origin;
|
|
302
|
+
l && l.part === r && s.push(l.spid);
|
|
303
|
+
for (const u of i.children ?? []) n(u);
|
|
304
|
+
};
|
|
305
|
+
return n(t.id), [...new Set(s)].sort((o, i) => o - i);
|
|
306
|
+
}
|
|
307
|
+
function F(e, t) {
|
|
308
|
+
const r = Ye(e, t);
|
|
309
|
+
return {
|
|
310
|
+
id: t.id,
|
|
311
|
+
parent: t.parent,
|
|
312
|
+
meta: structuredClone(t.meta),
|
|
313
|
+
...r.length ? { sourceSpids: r } : {}
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function Ze(e, t) {
|
|
317
|
+
let r = t;
|
|
318
|
+
const s = /* @__PURE__ */ new Set();
|
|
319
|
+
for (; !e.slides[r]; ) {
|
|
320
|
+
if (s.has(r)) throw new Error(`协同删除父链成环:${t}`);
|
|
321
|
+
s.add(r);
|
|
322
|
+
const n = e.elements[r];
|
|
323
|
+
if (!n) throw new Error(`协同删除找不到所属页:${t}`);
|
|
324
|
+
r = n.parent;
|
|
325
|
+
}
|
|
326
|
+
return r;
|
|
327
|
+
}
|
|
328
|
+
function et(e, t) {
|
|
329
|
+
if (t.op !== "remove") return t;
|
|
330
|
+
const r = e.elements[t.path[1]];
|
|
331
|
+
if (!!r && r.parent === t.value.parent && Object.entries(t.value.records).every(([d, w]) => {
|
|
332
|
+
var b;
|
|
333
|
+
return ((b = e.elements[d]) == null ? void 0 : b.parent) === w.parent;
|
|
334
|
+
})) return t;
|
|
335
|
+
const n = new Set(Object.keys(t.value.records).filter((d) => !!e.elements[d]));
|
|
336
|
+
if (r) {
|
|
337
|
+
const d = (w) => {
|
|
338
|
+
var p;
|
|
339
|
+
if (n.has(w)) {
|
|
340
|
+
for (const E of ((p = e.elements[w]) == null ? void 0 : p.children) ?? []) d(E);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const b = e.elements[w];
|
|
344
|
+
if (b) {
|
|
345
|
+
n.add(w);
|
|
346
|
+
for (const E of b.children ?? []) d(E);
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
d(r.id);
|
|
350
|
+
}
|
|
351
|
+
const c = [...n];
|
|
352
|
+
if (!c.length) return null;
|
|
353
|
+
const o = Object.fromEntries(c.map((d) => [d, null])), i = /* @__PURE__ */ Object.create(null), l = t.value.records[t.value.root];
|
|
354
|
+
if (l.meta.created) {
|
|
355
|
+
i[l.id] = null;
|
|
356
|
+
for (const d of Object.values(t.value.records))
|
|
357
|
+
!d.meta.created && d.meta.sourceParent !== void 0 && (i[d.id] = F(t.value, d));
|
|
358
|
+
} else i[l.id] = F(t.value, l);
|
|
359
|
+
for (const d of c)
|
|
360
|
+
Object.prototype.hasOwnProperty.call(t.value.records, d) || (i[d] = null);
|
|
361
|
+
const u = new Set(c), y = /* @__PURE__ */ Object.create(null);
|
|
362
|
+
for (const d of c) {
|
|
363
|
+
const w = e.elements[d].parent;
|
|
364
|
+
!u.has(w) && y[w] === void 0 && (y[w] = V(e, w).filter((b) => !u.has(b)));
|
|
365
|
+
}
|
|
366
|
+
const f = Ze(e, c[0]);
|
|
367
|
+
return {
|
|
368
|
+
op: "set",
|
|
369
|
+
path: ["elements", t.path[1], "hierarchy"],
|
|
370
|
+
origin: t.origin,
|
|
371
|
+
value: { parent: f, affected: c, records: o, children: y, removed: i }
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
function tt(e, t) {
|
|
375
|
+
if (t.op !== "insert" || !t.value.sectionId || e.sections.records[t.value.sectionId]) return t;
|
|
376
|
+
const { sectionId: r, ...s } = t.value;
|
|
377
|
+
return { ...t, value: s };
|
|
378
|
+
}
|
|
379
|
+
function rt(e, t) {
|
|
380
|
+
if (t.op !== "remove") return t;
|
|
381
|
+
const r = e.slides[t.path[1]];
|
|
382
|
+
if (!r) return null;
|
|
383
|
+
const s = /* @__PURE__ */ Object.create(null), n = (i) => {
|
|
384
|
+
const l = e.elements[i];
|
|
385
|
+
if (!l) throw new Error(`协同删页找不到当前元素:${i}`);
|
|
386
|
+
s[i] = structuredClone(l);
|
|
387
|
+
for (const u of l.children ?? []) n(u);
|
|
388
|
+
};
|
|
389
|
+
for (const i of r.children) n(i);
|
|
390
|
+
const c = e.slideOrder.indexOf(r.id);
|
|
391
|
+
if (c < 0) throw new Error(`协同删页找不到当前页序:${r.id}`);
|
|
392
|
+
const o = je(e, r.id);
|
|
393
|
+
return {
|
|
394
|
+
...t,
|
|
395
|
+
value: {
|
|
396
|
+
slide: structuredClone(r),
|
|
397
|
+
after: e.slideOrder[c - 1] ?? null,
|
|
398
|
+
before: e.slideOrder[c + 1] ?? null,
|
|
399
|
+
records: s,
|
|
400
|
+
...o ? { sectionId: o } : {}
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
const Se = (e, t) => e < t ? -1 : e > t ? 1 : 0;
|
|
405
|
+
function be(e, t, r) {
|
|
406
|
+
const s = t.indexOf(r), n = t.slice(0, s).reverse().find((u) => e.includes(u)) ?? null, c = t.slice(s + 1).find((u) => e.includes(u)) ?? null, o = n === null ? 0 : e.indexOf(n) + 1, i = c === null ? e.length : e.indexOf(c), l = [.../* @__PURE__ */ new Set([...e.slice(o, i), r])].sort(Se);
|
|
407
|
+
e.splice(o, i - o, ...l);
|
|
408
|
+
}
|
|
409
|
+
function nt(e, t, r) {
|
|
410
|
+
const s = t.records[r];
|
|
411
|
+
if (!s || e.records[r]) return !1;
|
|
412
|
+
const n = structuredClone(s);
|
|
413
|
+
for (const c of [...n.slideIds]) {
|
|
414
|
+
const o = e.order.find((i) => e.records[i].slideIds.includes(c));
|
|
415
|
+
o && (Se(o, r) < 0 ? n.slideIds.splice(n.slideIds.indexOf(c), 1) : e.records[o].slideIds.splice(e.records[o].slideIds.indexOf(c), 1));
|
|
416
|
+
}
|
|
417
|
+
return e.records[r] = n, be(e.order, t.order, r), !0;
|
|
418
|
+
}
|
|
419
|
+
function st(e, t) {
|
|
420
|
+
const r = t.path[2], s = t.path[3], n = t.value, c = structuredClone(e.sections);
|
|
421
|
+
let o = !1;
|
|
422
|
+
if (s === "name") {
|
|
423
|
+
if (!c.records[r] || !n.records[r]) return null;
|
|
424
|
+
o = c.records[r].name !== n.records[r].name, c.records[r].name = n.records[r].name;
|
|
425
|
+
} else if (s === "order") {
|
|
426
|
+
if (!c.records[r] || !n.records[r]) return null;
|
|
427
|
+
const i = c.order.join("\0");
|
|
428
|
+
c.order.splice(c.order.indexOf(r), 1), be(c.order, n.order, r), o = i !== c.order.join("\0");
|
|
429
|
+
} else n.records[r] ? o = nt(c, n, r) : c.records[r] && (delete c.records[r], c.order.splice(c.order.indexOf(r), 1), o = !0);
|
|
430
|
+
return c.edited || (c.edited = n.edited), !o && c.edited === e.sections.edited && s !== "order" ? null : { ...t, value: c };
|
|
431
|
+
}
|
|
432
|
+
const ot = ["x", "y", "w", "h", "rot", "flipH", "flipV"], J = (e) => `hierarchy:${JSON.stringify(e)}`, Y = (e) => e.path.length === 2 && e.path[0] === "elements" && (e.op === "insert" || e.op === "remove") ? { id: e.path[1], state: e.op === "insert" ? "present" : "removed" } : null, H = (e) => e.path.length === 2 && e.path[0] === "slides" && (e.op === "insert" || e.op === "remove") ? { id: e.path[1], state: e.op === "insert" ? "present" : "removed" } : null, Z = (e) => {
|
|
433
|
+
var r;
|
|
434
|
+
if (e.op !== "move" || e.path.length !== 2 || e.path[0] !== "slideOrder") return null;
|
|
435
|
+
const t = (r = e.value) == null ? void 0 : r.after;
|
|
436
|
+
return t === null || typeof t == "string" && t ? { id: e.path[1], after: t } : null;
|
|
437
|
+
}, ct = (e) => {
|
|
438
|
+
if (e.op !== "set" || e.path.length !== 4 || e.path[0] !== "document" || e.path[1] !== "sections" || !["state", "order"].includes(e.path[3])) return null;
|
|
439
|
+
const t = e.path[2], r = e.value;
|
|
440
|
+
if (!(r != null && r.records) || typeof r.records != "object" || !Array.isArray(r.order) || !(t in r.records)) return null;
|
|
441
|
+
const s = r.order.indexOf(t);
|
|
442
|
+
if (s < 0) return null;
|
|
443
|
+
const n = r.order[s - 1] ?? null;
|
|
444
|
+
return n === null || typeof n == "string" && n ? { id: t, after: n } : null;
|
|
445
|
+
}, ee = (e) => Be(e), L = (e, t) => !t || D(e, t.stamp) > 0;
|
|
446
|
+
function G(e, t, r) {
|
|
447
|
+
var l, u, y;
|
|
448
|
+
const s = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), c = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map(), i = /* @__PURE__ */ new Map();
|
|
449
|
+
for (let f = 0; f < t.length; f++) {
|
|
450
|
+
const d = t[f], w = ee(d);
|
|
451
|
+
if (w) {
|
|
452
|
+
const m = d.path[1], S = d.value;
|
|
453
|
+
for (const h of S.affected) s.set(J(h), "hierarchy");
|
|
454
|
+
for (const [h, I] of Object.entries(w))
|
|
455
|
+
n.set(h, I === null ? "removed" : "present"), I !== null && s.set(JSON.stringify(["elements", h, "order"]), "hierarchy");
|
|
456
|
+
if (w[m] === null) {
|
|
457
|
+
for (const [h, I] of Object.entries(S.records))
|
|
458
|
+
if (I !== null)
|
|
459
|
+
for (const a of ot)
|
|
460
|
+
s.set(JSON.stringify(["elements", h, "ovr", a]), "hierarchy");
|
|
461
|
+
}
|
|
462
|
+
s.set(X(d), "hierarchy");
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
const b = Y(d);
|
|
466
|
+
if (b) {
|
|
467
|
+
const m = (l = d.value) == null ? void 0 : l.records;
|
|
468
|
+
for (const S of Object.keys(m ?? { [b.id]: !0 }))
|
|
469
|
+
n.set(S, b.state), s.set(J(S), "hierarchy");
|
|
470
|
+
}
|
|
471
|
+
const p = H(d);
|
|
472
|
+
if (p) {
|
|
473
|
+
c.set(p.id, p.state);
|
|
474
|
+
const m = (u = d.value) == null ? void 0 : u.records;
|
|
475
|
+
for (const S of Object.keys(m ?? {}))
|
|
476
|
+
n.set(S, p.state), s.set(J(S), "hierarchy");
|
|
477
|
+
p.state === "present" && o.set(p.id, {
|
|
478
|
+
after: d.op === "insert" ? d.value.after : null,
|
|
479
|
+
ordinal: f
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
const E = Z(d);
|
|
483
|
+
E && o.set(E.id, { after: E.after, ordinal: f });
|
|
484
|
+
const g = ct(d);
|
|
485
|
+
g && i.set(g.id, { after: g.after, ordinal: f }), !b && !p && !E && !ge(d) && s.set(X(d), "field");
|
|
486
|
+
}
|
|
487
|
+
for (const [f, d] of s) {
|
|
488
|
+
const w = e.registers.get(f);
|
|
489
|
+
(!w || D(r, w.stamp) >= 0) && e.registers.set(f, { stamp: r, kind: d });
|
|
490
|
+
}
|
|
491
|
+
for (const [f, d] of n) {
|
|
492
|
+
const w = e.elementLifecycles.get(f);
|
|
493
|
+
(d === "removed" && (w == null ? void 0 : w.stamp.replicaId) !== r.replicaId || L(r, w)) && e.elementLifecycles.set(f, { stamp: r, state: d });
|
|
494
|
+
}
|
|
495
|
+
for (const [f, d] of c)
|
|
496
|
+
L(r, e.slideLifecycles.get(f)) && e.slideLifecycles.set(f, { stamp: r, state: d });
|
|
497
|
+
for (const [f, d] of o)
|
|
498
|
+
L(r, e.slideMoves.get(f)) && e.slideMoves.set(f, { stamp: r, ...d });
|
|
499
|
+
for (const [f, d] of i)
|
|
500
|
+
L(r, e.sectionMoves.get(f)) && e.sectionMoves.set(f, { stamp: r, ...d });
|
|
501
|
+
(y = e.onRecord) == null || y.call(e, t, r);
|
|
502
|
+
}
|
|
503
|
+
function it(e, t) {
|
|
504
|
+
const [r, s] = t.path;
|
|
505
|
+
return r === "elements" && typeof s == "string" ? !!e.elements[s] : (r === "slides" || r === "slideOrder") && typeof s == "string" ? !!e.slides[s] : r === "layouts" && typeof s == "string" ? !!e.layouts[s] : r === "masters" && typeof s == "string" ? !!e.masters[s] : !0;
|
|
506
|
+
}
|
|
507
|
+
function lt(e) {
|
|
508
|
+
if (e.path.length !== 5 || e.path[0] !== "elements" || e.path[2] !== "ovr" || !["tableRemovedRows", "tableRemovedColumns"].includes(String(e.path[3]))) return null;
|
|
509
|
+
const t = e.path[3];
|
|
510
|
+
return {
|
|
511
|
+
elementId: e.path[1],
|
|
512
|
+
dimension: t === "tableRemovedRows" ? "row" : "column",
|
|
513
|
+
field: t,
|
|
514
|
+
id: e.path[4],
|
|
515
|
+
patch: e
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
function dt(e, t, r, s) {
|
|
519
|
+
var c;
|
|
520
|
+
const n = JSON.stringify(["elements", t, "ovr", r, s]);
|
|
521
|
+
return ((c = e.registers.get(n)) == null ? void 0 : c.stamp) ?? { clock: 0, replicaId: "" };
|
|
522
|
+
}
|
|
523
|
+
function at(e, t, r, s) {
|
|
524
|
+
const n = r.get(s);
|
|
525
|
+
if (n) return n;
|
|
526
|
+
const c = e.elements[s];
|
|
527
|
+
if (!c || c.src.kind !== "table") throw new Error(`协同表格不存在:${s}`);
|
|
528
|
+
const o = Le(e, s), i = (u, y, f) => {
|
|
529
|
+
const d = u === "row" ? c.ovr.tableRemovedRows : c.ovr.tableRemovedColumns, w = new Set(Object.keys(d ?? {}));
|
|
530
|
+
return {
|
|
531
|
+
all: y,
|
|
532
|
+
removed: w,
|
|
533
|
+
stamps: new Map([...w].map((b) => [b, dt(t, s, f, b)]))
|
|
534
|
+
};
|
|
535
|
+
}, l = {
|
|
536
|
+
rows: i("row", o.rows, "tableRemovedRows"),
|
|
537
|
+
columns: i("column", o.columns, "tableRemovedColumns")
|
|
538
|
+
};
|
|
539
|
+
return r.set(s, l), l;
|
|
540
|
+
}
|
|
541
|
+
function ft(e, t) {
|
|
542
|
+
return {
|
|
543
|
+
op: "del",
|
|
544
|
+
path: ["elements", e.elementId, "ovr", e.field, t],
|
|
545
|
+
origin: e.patch.origin
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
function ut(e) {
|
|
549
|
+
return [...e.removed].sort((t, r) => D(e.stamps.get(t), e.stamps.get(r)) || (t < r ? -1 : t > r ? 1 : 0))[0];
|
|
550
|
+
}
|
|
551
|
+
function pt(e, t, r, s) {
|
|
552
|
+
const n = [], c = [], o = /* @__PURE__ */ new Map(), i = (l, u = !1) => {
|
|
553
|
+
n.push(l), u && c.push(l);
|
|
554
|
+
};
|
|
555
|
+
for (const l of s) {
|
|
556
|
+
const u = lt(l);
|
|
557
|
+
if (u) {
|
|
558
|
+
const y = at(e, t, o, u.elementId), f = u.dimension === "row" ? y.rows : y.columns;
|
|
559
|
+
if (l.op === "del") {
|
|
560
|
+
f.removed.delete(u.id), f.stamps.delete(u.id), i(l);
|
|
561
|
+
continue;
|
|
562
|
+
}
|
|
563
|
+
if (f.removed.add(u.id), f.stamps.set(u.id, r), f.removed.size >= f.all.length) {
|
|
564
|
+
const d = ut(f);
|
|
565
|
+
f.removed.delete(d), f.stamps.delete(d);
|
|
566
|
+
const w = ft(u, d);
|
|
567
|
+
if (i(w, !0), d === u.id) continue;
|
|
568
|
+
}
|
|
569
|
+
i(l);
|
|
570
|
+
continue;
|
|
571
|
+
}
|
|
572
|
+
i(l);
|
|
573
|
+
}
|
|
574
|
+
return { accepted: n, recorded: c };
|
|
575
|
+
}
|
|
576
|
+
function Ie(e, t) {
|
|
577
|
+
var s;
|
|
578
|
+
if (!((s = e.extensions) != null && s[ke])) return t;
|
|
579
|
+
const r = /* @__PURE__ */ new Map();
|
|
580
|
+
for (const [n, c] of t) {
|
|
581
|
+
let o = n;
|
|
582
|
+
try {
|
|
583
|
+
n.startsWith('["elements",') && (o = JSON.stringify(Pe(e, JSON.parse(n))));
|
|
584
|
+
} catch {
|
|
585
|
+
}
|
|
586
|
+
L(c.stamp, r.get(o)) && r.set(o, c);
|
|
587
|
+
}
|
|
588
|
+
return r;
|
|
589
|
+
}
|
|
590
|
+
function U(e, t) {
|
|
591
|
+
const r = {
|
|
592
|
+
elements: new Set(t == null ? void 0 : t.elements),
|
|
593
|
+
slides: new Set(t == null ? void 0 : t.slides)
|
|
594
|
+
};
|
|
595
|
+
for (const s of e) {
|
|
596
|
+
const n = Y(s);
|
|
597
|
+
(n == null ? void 0 : n.state) === "present" && Object.keys(s.value.records).forEach((o) => r.elements.add(o));
|
|
598
|
+
const c = H(s);
|
|
599
|
+
if ((c == null ? void 0 : c.state) === "present" && (r.slides.add(c.id), Object.keys(s.value.records).forEach((o) => r.elements.add(o))), ee(s))
|
|
600
|
+
for (const [o, i] of Object.entries(
|
|
601
|
+
s.value.records
|
|
602
|
+
)) i && r.elements.add(o);
|
|
603
|
+
}
|
|
604
|
+
return r;
|
|
605
|
+
}
|
|
606
|
+
function ue(e, t, r) {
|
|
607
|
+
var c, o;
|
|
608
|
+
const [s, n] = e.path;
|
|
609
|
+
return s === "elements" && typeof n == "string" ? ((c = t.get(n)) == null ? void 0 : c.state) === "removed" : (s === "slides" || s === "slideOrder") && typeof n == "string" ? ((o = r.get(n)) == null ? void 0 : o.state) === "removed" : !1;
|
|
610
|
+
}
|
|
611
|
+
function pe(e, t, r) {
|
|
612
|
+
const [s, n] = t.path;
|
|
613
|
+
return s === "elements" && r.elements.has(n) || (s === "slides" || s === "slideOrder") && r.slides.has(n) ? !0 : it(e, t);
|
|
614
|
+
}
|
|
615
|
+
function he(e, t, r) {
|
|
616
|
+
return !!e.elements[t] || !!e.slides[t] || !!e.layouts[t] || !!e.masters[t] || r.elements.has(t) || r.slides.has(t);
|
|
617
|
+
}
|
|
618
|
+
const ht = (e) => e.op === "set" && e.path.length === 4 && e.path[0] === "document" && e.path[1] === "sections" && typeof e.path[2] == "string" && ["state", "name", "order"].includes(e.path[3]);
|
|
619
|
+
function mt(e, t, r, s, n) {
|
|
620
|
+
var d, w;
|
|
621
|
+
const c = r.patches.filter(B);
|
|
622
|
+
if (c.length) {
|
|
623
|
+
if (r.patches.slice(0, c.length).some((b) => !B(b)))
|
|
624
|
+
throw new Error("协同地址声明必须先于字段和结构补丁");
|
|
625
|
+
e = N(e, c);
|
|
626
|
+
}
|
|
627
|
+
const o = n ?? Ae(e, r.patches);
|
|
628
|
+
o.length && (e = N(e, o)), t = { ...t, registers: Ie(e, t.registers) };
|
|
629
|
+
const i = [...o], l = [], u = U([], s);
|
|
630
|
+
let y = !1;
|
|
631
|
+
for (const b of r.patches) {
|
|
632
|
+
const p = qe(e, b);
|
|
633
|
+
if (ge(p)) throw new Error("迁移凭据须本地裁决");
|
|
634
|
+
if (B(p)) {
|
|
635
|
+
i.push(p), l.push(p);
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
const E = Y(p), g = H(p), m = Z(p), S = ee(p);
|
|
639
|
+
if (ht(p)) {
|
|
640
|
+
if (!L(r.stamp, t.registers.get(X(p)))) continue;
|
|
641
|
+
const h = i.length ? N(e, i) : e, I = st(h, p);
|
|
642
|
+
I && i.push(I), l.push(p);
|
|
643
|
+
continue;
|
|
644
|
+
}
|
|
645
|
+
if (E) {
|
|
646
|
+
if (E.state === "removed") {
|
|
647
|
+
const I = t.elementLifecycles.get(E.id);
|
|
648
|
+
if ((I == null ? void 0 : I.stamp.replicaId) === r.replicaId && !L(r.stamp, I)) continue;
|
|
649
|
+
const a = et(e, p);
|
|
650
|
+
a && i.push(a), l.push(p), a && a !== p && l.push(a);
|
|
651
|
+
continue;
|
|
652
|
+
}
|
|
653
|
+
if (!L(r.stamp, t.elementLifecycles.get(E.id))) continue;
|
|
654
|
+
const h = p.value.parent;
|
|
655
|
+
if (((d = t.slideLifecycles.get(h)) == null ? void 0 : d.state) === "removed" || ((w = t.elementLifecycles.get(h)) == null ? void 0 : w.state) === "removed") {
|
|
656
|
+
l.push({ ...p, op: "remove" });
|
|
657
|
+
continue;
|
|
658
|
+
}
|
|
659
|
+
he(e, h, u) || (y = !0), e.elements[E.id] || (i.push(p), Object.keys(p.value.records).forEach((I) => u.elements.add(I))), l.push(p);
|
|
660
|
+
continue;
|
|
661
|
+
}
|
|
662
|
+
if (g) {
|
|
663
|
+
if (!L(r.stamp, t.slideLifecycles.get(g.id))) continue;
|
|
664
|
+
if (g.state === "removed") {
|
|
665
|
+
const h = rt(e, p);
|
|
666
|
+
h && i.push(h), l.push(h ?? p);
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
if (!e.slides[g.id]) {
|
|
670
|
+
const h = i.length ? N(e, i) : e;
|
|
671
|
+
i.push(tt(h, p)), u.slides.add(g.id), Object.keys(p.value.records).forEach((I) => u.elements.add(I));
|
|
672
|
+
}
|
|
673
|
+
l.push(p);
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
if (S) {
|
|
677
|
+
const h = p;
|
|
678
|
+
he(e, h.value.parent, u) || (y = !0);
|
|
679
|
+
const I = new Set([...t.elementLifecycles].flatMap(([M, C]) => C.state === "removed" ? [M] : [])), a = new Set(h.value.affected.filter((M) => !L(r.stamp, t.registers.get(J(M))))), v = Ke(h, a), O = v && Ge(
|
|
680
|
+
e,
|
|
681
|
+
v,
|
|
682
|
+
I
|
|
683
|
+
);
|
|
684
|
+
if (O) {
|
|
685
|
+
const M = O.value.records[O.path[1]] === null, C = Qe(e, O, (j, k) => {
|
|
686
|
+
const $ = k === "order" ? ["elements", j, "order"] : ["elements", j, "ovr", k], x = t.registers.get(JSON.stringify($));
|
|
687
|
+
return M && (x == null ? void 0 : x.kind) === "hierarchy" || L(r.stamp, x);
|
|
688
|
+
});
|
|
689
|
+
i.push(C), l.push(C), Object.entries(C.value.records).forEach(([j, k]) => {
|
|
690
|
+
k && u.elements.add(j);
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
continue;
|
|
694
|
+
}
|
|
695
|
+
if (m) {
|
|
696
|
+
if (!L(r.stamp, t.slideMoves.get(m.id))) continue;
|
|
697
|
+
ue(p, t.elementLifecycles, t.slideLifecycles) ? l.push(p) : pe(e, p, u) ? (i.push(p), l.push(p)) : y = !0;
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
L(r.stamp, t.registers.get(X(p))) && (ue(p, t.elementLifecycles, t.slideLifecycles) ? l.push(p) : pe(e, p, u) ? (i.push(p), l.push(p)) : y = !0);
|
|
701
|
+
}
|
|
702
|
+
const f = pt(e, t, r.stamp, i);
|
|
703
|
+
return {
|
|
704
|
+
accepted: f.accepted,
|
|
705
|
+
recorded: [...l, ...f.recorded],
|
|
706
|
+
missingDependency: y,
|
|
707
|
+
availability: u
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
function Oe(e, t, r) {
|
|
711
|
+
const s = e.filter((c) => t.has(c));
|
|
712
|
+
s.push(...[...t].filter((c) => !s.includes(c)).sort());
|
|
713
|
+
const n = [...r.entries()].sort((c, o) => D(c[1].stamp, o[1].stamp) || c[1].ordinal - o[1].ordinal || (c[0] < o[0] ? -1 : c[0] === o[0] ? 0 : 1));
|
|
714
|
+
for (const [c, o] of n) {
|
|
715
|
+
const i = s.indexOf(c);
|
|
716
|
+
if (i < 0) continue;
|
|
717
|
+
s.splice(i, 1);
|
|
718
|
+
const l = o.after === null ? -1 : s.indexOf(o.after);
|
|
719
|
+
s.splice(l < 0 && o.after !== null ? s.length : l + 1, 0, c);
|
|
720
|
+
}
|
|
721
|
+
return s;
|
|
722
|
+
}
|
|
723
|
+
function gt(e, t) {
|
|
724
|
+
const r = [...e], s = [];
|
|
725
|
+
for (let n = 0; n < t.length; n++) {
|
|
726
|
+
const c = t[n], o = t[n - 1] ?? null, i = r.indexOf(c);
|
|
727
|
+
if ((i > 0 ? r[i - 1] : null) === o) continue;
|
|
728
|
+
r.splice(i, 1);
|
|
729
|
+
const u = o === null ? -1 : r.indexOf(o);
|
|
730
|
+
r.splice(u + 1, 0, c), s.push({ op: "move", path: ["slideOrder", c], value: { after: o }, origin: "collab-order" });
|
|
731
|
+
}
|
|
732
|
+
return s;
|
|
733
|
+
}
|
|
734
|
+
function vt(e, t, r) {
|
|
735
|
+
const s = /* @__PURE__ */ new Map(), n = [], c = [];
|
|
736
|
+
for (const f of r)
|
|
737
|
+
if (!Z(f))
|
|
738
|
+
if (f.path.length === 2 && f.path[0] === "slides" && (f.op === "insert" || f.op === "remove")) {
|
|
739
|
+
const d = structuredClone(f);
|
|
740
|
+
d.op === "insert" ? s.set(d.path[1], d) : n.push(d);
|
|
741
|
+
} else c.push(f);
|
|
742
|
+
const o = new Set(n.map((f) => f.path[1])), i = e.filter((f) => !o.has(f)), l = t.filter((f) => !s.has(f)), u = gt(i, l), y = [];
|
|
743
|
+
for (let f = 0; f < t.length; f++) {
|
|
744
|
+
const d = t[f], w = s.get(d);
|
|
745
|
+
w && y.push({
|
|
746
|
+
...w,
|
|
747
|
+
value: { ...w.value, after: t[f - 1] ?? null }
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
return [...n, ...u, ...y, ...c];
|
|
751
|
+
}
|
|
752
|
+
function yt(e, t, r) {
|
|
753
|
+
let s = -1;
|
|
754
|
+
for (let o = 0; o < r.length; o++) {
|
|
755
|
+
const i = r[o];
|
|
756
|
+
i.op === "set" && i.path.length === 4 && i.path[0] === "document" && i.path[1] === "sections" && (s = o);
|
|
757
|
+
}
|
|
758
|
+
if (s < 0) return r;
|
|
759
|
+
const n = r[s], c = Oe(e, new Set(Object.keys(n.value.records)), t);
|
|
760
|
+
return r[s] = { ...n, value: { ...n.value, order: c } }, r;
|
|
761
|
+
}
|
|
762
|
+
const W = /* @__PURE__ */ new WeakMap(), wt = 1e4;
|
|
763
|
+
function Mt(e) {
|
|
764
|
+
const t = W.get(e);
|
|
765
|
+
if (!t) throw new Error("编辑器尚未绑定协同会话");
|
|
766
|
+
return t;
|
|
767
|
+
}
|
|
768
|
+
function me(e, t) {
|
|
769
|
+
if (!e || e.length > 128 || /[\0-\x1f\x7f]/.test(e))
|
|
770
|
+
throw new Error(`${t} 必须是 1–128 个不含控制字符的字符`);
|
|
771
|
+
}
|
|
772
|
+
function St(e, t, r) {
|
|
773
|
+
const s = e.doc.identity.allocation;
|
|
774
|
+
return r = structuredClone(r), {
|
|
775
|
+
documentId: t.documentId,
|
|
776
|
+
replicaId: t.replicaId,
|
|
777
|
+
replicaSlot: t.replicaSlot,
|
|
778
|
+
registers: new Map(r == null ? void 0 : r.registers),
|
|
779
|
+
elementLifecycles: new Map(r == null ? void 0 : r.elementLifecycles),
|
|
780
|
+
slideLifecycles: new Map(r == null ? void 0 : r.slideLifecycles),
|
|
781
|
+
slideMoves: new Map(r == null ? void 0 : r.slideMoves),
|
|
782
|
+
sectionMoves: new Map(r == null ? void 0 : r.sectionMoves),
|
|
783
|
+
seen: _e(r == null ? void 0 : r.seen),
|
|
784
|
+
baseSlideOrder: [...(r == null ? void 0 : r.baseSlideOrder) ?? e.doc.slideOrder],
|
|
785
|
+
baseSectionOrder: [...(r == null ? void 0 : r.baseSectionOrder) ?? e.doc.sections.order],
|
|
786
|
+
deferred: [...(r == null ? void 0 : r.deferred) ?? []],
|
|
787
|
+
clock: s.clock,
|
|
788
|
+
sequence: s.sequence,
|
|
789
|
+
active: !1
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
function bt(e, t) {
|
|
793
|
+
return structuredClone({
|
|
794
|
+
version: 1,
|
|
795
|
+
documentId: e.documentId,
|
|
796
|
+
replicaId: e.replicaId,
|
|
797
|
+
replicaSlot: e.replicaSlot,
|
|
798
|
+
clock: e.clock,
|
|
799
|
+
sequence: e.sequence,
|
|
800
|
+
baseSlideOrder: e.baseSlideOrder,
|
|
801
|
+
baseSectionOrder: e.baseSectionOrder,
|
|
802
|
+
registers: [...Ie(t, e.registers)],
|
|
803
|
+
elementLifecycles: [...e.elementLifecycles],
|
|
804
|
+
slideLifecycles: [...e.slideLifecycles],
|
|
805
|
+
slideMoves: [...e.slideMoves],
|
|
806
|
+
sectionMoves: [...e.sectionMoves],
|
|
807
|
+
seen: De(e.seen),
|
|
808
|
+
deferred: e.deferred
|
|
809
|
+
});
|
|
810
|
+
}
|
|
811
|
+
function It(e, t) {
|
|
812
|
+
if (e.active) throw new Error("同一个 Editor 已经绑定协同 provider");
|
|
813
|
+
if (e.documentId !== t.documentId || e.replicaId !== t.replicaId || e.replicaSlot !== t.replicaSlot)
|
|
814
|
+
throw new Error("同一个 Editor 不能切换协同文档或副本身份");
|
|
815
|
+
}
|
|
816
|
+
const Ct = Ot;
|
|
817
|
+
function Ot(e, t, r = mt) {
|
|
818
|
+
if (!e || typeof e.subscribePatches != "function" || typeof e.applyExternalPatches != "function")
|
|
819
|
+
throw new Error("协同绑定需要支持外部补丁的 Editor");
|
|
820
|
+
if (me(t.documentId, "documentId"), me(t.replicaId, "replicaId"), !t.provider || typeof t.provider.send != "function" || typeof t.provider.subscribe != "function") throw new Error("provider 接口无效");
|
|
821
|
+
if (!Number.isSafeInteger(t.replicaSlot) || t.replicaSlot < 0 || t.replicaSlot >= 4096)
|
|
822
|
+
throw new Error("replicaSlot 必须是 0–4095 的整数");
|
|
823
|
+
let s = W.get(e);
|
|
824
|
+
const n = !s;
|
|
825
|
+
let c = null;
|
|
826
|
+
if (s) It(s, t);
|
|
827
|
+
else {
|
|
828
|
+
const a = e.doc.identity.allocation, v = (a == null ? void 0 : a.replicaId) === t.replicaId && a.slot === t.replicaSlot && a.count === 4096;
|
|
829
|
+
if (e.history.undoCount || e.history.redoCount || e.isDirty() && !v)
|
|
830
|
+
throw new Error("协同绑定必须在本地编辑开始前建立");
|
|
831
|
+
c = structuredClone(e.doc.identity);
|
|
832
|
+
try {
|
|
833
|
+
Ne(e.doc, t.replicaId, t.replicaSlot);
|
|
834
|
+
const O = e.doc.identity.allocation;
|
|
835
|
+
if ((O.clock > 0 || O.sequence > 0) && !t.checkpoint)
|
|
836
|
+
throw new Error("恢复协同文档必须同时提供 CollaborationCheckpoint");
|
|
837
|
+
t.checkpoint && Xe(t.checkpoint, t, O), s = St(e, t, t.checkpoint), W.set(e, s);
|
|
838
|
+
} catch (O) {
|
|
839
|
+
throw e.doc.identity = c, O;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
const o = s, i = (a) => {
|
|
843
|
+
var v;
|
|
844
|
+
try {
|
|
845
|
+
(v = t.onError) == null || v.call(t, a);
|
|
846
|
+
} catch {
|
|
847
|
+
}
|
|
848
|
+
}, l = () => ({
|
|
849
|
+
registers: new Map(o.registers),
|
|
850
|
+
elementLifecycles: new Map(o.elementLifecycles),
|
|
851
|
+
slideLifecycles: new Map(o.slideLifecycles),
|
|
852
|
+
slideMoves: new Map(o.slideMoves),
|
|
853
|
+
sectionMoves: new Map(o.sectionMoves),
|
|
854
|
+
seen: ze(o.seen),
|
|
855
|
+
deferred: [...o.deferred],
|
|
856
|
+
clock: o.clock
|
|
857
|
+
}), u = (a) => {
|
|
858
|
+
Object.assign(o, a);
|
|
859
|
+
}, y = (a) => {
|
|
860
|
+
const v = Fe(a), O = new Set(e.doc.slideOrder);
|
|
861
|
+
for (const C of v) {
|
|
862
|
+
const j = H(C);
|
|
863
|
+
j && (j.state === "present" ? O.add(j.id) : O.delete(j.id));
|
|
864
|
+
}
|
|
865
|
+
const M = Oe(
|
|
866
|
+
o.baseSlideOrder,
|
|
867
|
+
O,
|
|
868
|
+
o.slideMoves
|
|
869
|
+
);
|
|
870
|
+
return yt(
|
|
871
|
+
o.baseSectionOrder,
|
|
872
|
+
o.sectionMoves,
|
|
873
|
+
vt(e.doc.slideOrder, M, v)
|
|
874
|
+
);
|
|
875
|
+
}, f = (a, v) => {
|
|
876
|
+
const O = [], M = [];
|
|
877
|
+
let C = a, j = N(
|
|
878
|
+
e.doc,
|
|
879
|
+
y(v)
|
|
880
|
+
), k = !0;
|
|
881
|
+
for (; k; ) {
|
|
882
|
+
k = !1;
|
|
883
|
+
const $ = [...o.deferred].sort((P, R) => D(P.message.stamp, R.message.stamp) || P.ordinal - R.ordinal), x = /* @__PURE__ */ new Map();
|
|
884
|
+
for (const P of $) {
|
|
885
|
+
const R = $e(P.message), T = x.get(R) ?? [];
|
|
886
|
+
T.push(P), x.set(R, T);
|
|
887
|
+
}
|
|
888
|
+
const q = /* @__PURE__ */ new Set();
|
|
889
|
+
for (const P of x.values()) {
|
|
890
|
+
const R = P[0].message;
|
|
891
|
+
if (q.has(R.replicaId)) continue;
|
|
892
|
+
if (ne(o.seen, R)) {
|
|
893
|
+
q.add(R.replicaId);
|
|
894
|
+
continue;
|
|
895
|
+
}
|
|
896
|
+
const T = l(), Ee = new Set(P);
|
|
897
|
+
try {
|
|
898
|
+
const A = r(j, o, R, C);
|
|
899
|
+
if (A.missingDependency) {
|
|
900
|
+
q.add(R.replicaId);
|
|
901
|
+
continue;
|
|
902
|
+
}
|
|
903
|
+
G(o, A.recorded, R.stamp);
|
|
904
|
+
const Me = N(e.doc, y([
|
|
905
|
+
...v,
|
|
906
|
+
...O,
|
|
907
|
+
...A.accepted
|
|
908
|
+
])), Ce = U(A.accepted, C);
|
|
909
|
+
O.push(...A.accepted), j = Me, C = Ce;
|
|
910
|
+
} catch (A) {
|
|
911
|
+
u(T), M.push(A);
|
|
912
|
+
}
|
|
913
|
+
o.deferred = o.deferred.filter((A) => !Ee.has(A)), k = !0;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
return { patches: O, errors: M };
|
|
917
|
+
}, d = (a) => {
|
|
918
|
+
try {
|
|
919
|
+
if (ve(a), a.documentId !== t.documentId || a.replicaId === t.replicaId) return;
|
|
920
|
+
if (a.identity.prefix !== e.doc.identity.prefix)
|
|
921
|
+
throw new Error("协同消息的文档身份前缀与本地基线不一致");
|
|
922
|
+
if (Te(o.seen, a)) return;
|
|
923
|
+
const v = r(e.doc, o, a), M = ne(o.seen, a) || o.deferred.some((x) => x.message.replicaId === a.replicaId && x.message.sequence < a.sequence) || v.missingDependency ? a.patches.map((x, q) => ({ message: a, patch: x, ordinal: q })) : [];
|
|
924
|
+
if (o.deferred.length + M.length > wt)
|
|
925
|
+
throw new Error("协同延迟补丁超过安全上限");
|
|
926
|
+
const C = e.doc.identity.allocation, j = l(), k = C.clock;
|
|
927
|
+
let $ = [];
|
|
928
|
+
try {
|
|
929
|
+
const x = Math.max(o.clock, a.stamp.clock);
|
|
930
|
+
o.clock = x, C.clock = x, se(o.seen, a), M.length ? o.deferred.push(...M) : G(o, v.recorded, a.stamp), M.length || N(
|
|
931
|
+
e.doc,
|
|
932
|
+
y(v.accepted)
|
|
933
|
+
);
|
|
934
|
+
const q = M.length ? { patches: [], errors: [] } : f(U(v.accepted), v.accepted);
|
|
935
|
+
$ = q.errors;
|
|
936
|
+
const P = M.length ? [] : [...v.accepted, ...q.patches], R = y(P);
|
|
937
|
+
R.length ? e.applyExternalPatches(R, {
|
|
938
|
+
identity: a.identity,
|
|
939
|
+
origin: `collab:${a.replicaId}`,
|
|
940
|
+
label: a.label,
|
|
941
|
+
time: a.time
|
|
942
|
+
}) : e.applyExternalPatches([], {
|
|
943
|
+
identity: a.identity,
|
|
944
|
+
origin: `collab:${a.replicaId}`
|
|
945
|
+
});
|
|
946
|
+
} catch (x) {
|
|
947
|
+
throw u(j), C.clock = k, x;
|
|
948
|
+
}
|
|
949
|
+
$.forEach(i);
|
|
950
|
+
} catch (v) {
|
|
951
|
+
i(v);
|
|
952
|
+
}
|
|
953
|
+
}, w = /* @__PURE__ */ new Map(), b = (a) => {
|
|
954
|
+
if (!o.active || a.source === "external" || !a.patches.length) return;
|
|
955
|
+
const v = a.identity.allocation;
|
|
956
|
+
if (!v || v.replicaId !== t.replicaId || v.slot !== t.replicaSlot) {
|
|
957
|
+
i(new Error("本地补丁缺少匹配的协同身份版本"));
|
|
958
|
+
return;
|
|
959
|
+
}
|
|
960
|
+
if (v.clock <= o.clock || v.sequence <= o.sequence) {
|
|
961
|
+
i(new Error("协同逻辑时钟或消息序号已耗尽"));
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
o.clock = v.clock, o.sequence = v.sequence;
|
|
965
|
+
const O = { clock: v.clock, replicaId: t.replicaId }, M = v.sequence;
|
|
966
|
+
G(o, a.patches, O);
|
|
967
|
+
const C = {
|
|
968
|
+
version: 1,
|
|
969
|
+
documentId: t.documentId,
|
|
970
|
+
replicaId: t.replicaId,
|
|
971
|
+
sequence: M,
|
|
972
|
+
stamp: O,
|
|
973
|
+
patches: a.patches,
|
|
974
|
+
identity: a.identity,
|
|
975
|
+
label: a.label,
|
|
976
|
+
time: a.time
|
|
977
|
+
};
|
|
978
|
+
se(o.seen, C), w.set(M, C);
|
|
979
|
+
}, p = (a) => {
|
|
980
|
+
var M;
|
|
981
|
+
if (!o.active || a.source === "external" || !a.patches.length) return;
|
|
982
|
+
const v = (M = a.identity.allocation) == null ? void 0 : M.sequence, O = v === void 0 ? void 0 : w.get(v);
|
|
983
|
+
if (!O) {
|
|
984
|
+
i(new Error("本地补丁缺少 recovery 前协同 checkpoint"));
|
|
985
|
+
return;
|
|
986
|
+
}
|
|
987
|
+
w.delete(O.sequence);
|
|
988
|
+
try {
|
|
989
|
+
const C = t.provider.send(structuredClone(O));
|
|
990
|
+
C && typeof C.then == "function" && C.catch(i);
|
|
991
|
+
} catch (C) {
|
|
992
|
+
i(C);
|
|
993
|
+
}
|
|
994
|
+
};
|
|
995
|
+
let E = null, g = null, m = null;
|
|
996
|
+
const S = [];
|
|
997
|
+
let h = !1, I = !1;
|
|
998
|
+
try {
|
|
999
|
+
E = e.subscribePatches(b, { phase: "before-recovery" }), g = e.subscribePatches(p);
|
|
1000
|
+
const a = t.provider.subscribe((v) => {
|
|
1001
|
+
I || (h ? d(v) : S.push(structuredClone(v)));
|
|
1002
|
+
});
|
|
1003
|
+
if (typeof a != "function") throw new Error("provider.subscribe 必须返回取消订阅函数");
|
|
1004
|
+
m = a, o.active = !0, h = !0;
|
|
1005
|
+
for (const v of S) d(v);
|
|
1006
|
+
} catch (a) {
|
|
1007
|
+
try {
|
|
1008
|
+
E == null || E();
|
|
1009
|
+
} catch {
|
|
1010
|
+
}
|
|
1011
|
+
try {
|
|
1012
|
+
g == null || g();
|
|
1013
|
+
} catch {
|
|
1014
|
+
}
|
|
1015
|
+
try {
|
|
1016
|
+
m == null || m();
|
|
1017
|
+
} catch {
|
|
1018
|
+
}
|
|
1019
|
+
throw n && c && (e.doc.identity = c, W.delete(e)), a;
|
|
1020
|
+
}
|
|
1021
|
+
return {
|
|
1022
|
+
documentId: t.documentId,
|
|
1023
|
+
replicaId: t.replicaId,
|
|
1024
|
+
editor: e,
|
|
1025
|
+
checkpoint: () => bt(o, e.doc),
|
|
1026
|
+
dispose() {
|
|
1027
|
+
if (!I) {
|
|
1028
|
+
I = !0, o.active = !1, h = !1, S.length = 0, w.clear();
|
|
1029
|
+
try {
|
|
1030
|
+
E == null || E();
|
|
1031
|
+
} catch (a) {
|
|
1032
|
+
i(a);
|
|
1033
|
+
}
|
|
1034
|
+
try {
|
|
1035
|
+
g == null || g();
|
|
1036
|
+
} catch (a) {
|
|
1037
|
+
i(a);
|
|
1038
|
+
}
|
|
1039
|
+
try {
|
|
1040
|
+
m == null || m();
|
|
1041
|
+
} catch (a) {
|
|
1042
|
+
i(a);
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
}
|
|
1048
|
+
export {
|
|
1049
|
+
Ie as a,
|
|
1050
|
+
Ot as b,
|
|
1051
|
+
D as c,
|
|
1052
|
+
Oe as d,
|
|
1053
|
+
mt as e,
|
|
1054
|
+
Mt as f,
|
|
1055
|
+
Ct as g,
|
|
1056
|
+
vt as m,
|
|
1057
|
+
X as p,
|
|
1058
|
+
G as r,
|
|
1059
|
+
H as s
|
|
1060
|
+
};
|