kindy-editor 3.2.2 → 3.2.3

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.
Files changed (47) hide show
  1. package/dist-lib/assets/{worker-CHtzL1YW.js → worker-BIFTSRF2.js} +7043 -7021
  2. package/dist-lib/{browser-BxYyzpLt.js → browser-xuRja-pP.js} +2 -2
  3. package/dist-lib/builder.js +7 -7
  4. package/dist-lib/changeAggregator-ymKDXGA8.js +376 -0
  5. package/dist-lib/{editorApp-N20nk5uQ.js → editorApp-zIpjgEaZ.js} +7281 -7230
  6. package/dist-lib/events.js +119 -43
  7. package/dist-lib/export.js +1739 -1732
  8. package/dist-lib/generate-toc.js +5 -5
  9. package/dist-lib/import.js +2 -2
  10. package/dist-lib/{kindy-editor-D4xSNtvA.js → kindy-editor-DuN692fi.js} +5 -5
  11. package/dist-lib/kindy-editor.js +9 -6
  12. package/dist-lib/{lists-DpmgbDyt.js → lists-BVCy5dMa.js} +2 -2
  13. package/dist-lib/measure.js +3 -3
  14. package/dist-lib/{measureHost-C2NOdNkI.js → measureHost-y37gLU6M.js} +2 -2
  15. package/dist-lib/{metrics-DHgtBP-R.js → metrics-CdfHD-8y.js} +3 -3
  16. package/dist-lib/{paintStyle-Cjk9egel.js → paintStyle-Cb7IGKPW.js} +51 -51
  17. package/dist-lib/{parse-JE_w0NNt.js → parse-DJZd-2A7.js} +20 -20
  18. package/dist-lib/{pipeline-CgbvBwNe.js → pipeline-DKgBMmw1.js} +301 -301
  19. package/dist-lib/recalc-docx.js +2 -2
  20. package/dist-lib/{recalcToc-DKJK9f5X.js → recalcToc-DCykIt4o.js} +80 -80
  21. package/dist-lib/{styleProps-OePkgWnD.js → styleProps-Dg3Wf-ZJ.js} +3 -3
  22. package/dist-lib/{stylesheet-COz2MSt6.js → stylesheet-EQFx9l5c.js} +3 -3
  23. package/dist-lib/{toc-C6XLbDEA.js → toc-BIj8uQ-W.js} +48 -48
  24. package/dist-lib/{webmcp-DrpPKUeh.js → webmcp-QA5rVg1F.js} +2 -2
  25. package/docs/http-event-sink.md +7 -0
  26. package/docs/public-events.md +102 -0
  27. package/docs/track-changes-events.md +551 -0
  28. package/package.json +2 -2
  29. package/types/events.d.ts +67 -1
  30. package/types/kindy-editor.d.ts +4 -0
  31. package/dist-lib/eventHub-CZFpTVqe.js +0 -71
  32. package/dist-lib/events-D_WEQDa6.js +0 -104
  33. package/docs/.vitepress/cache/deps/@theme_index.js +0 -275
  34. package/docs/.vitepress/cache/deps/@theme_index.js.map +0 -7
  35. package/docs/.vitepress/cache/deps/_metadata.json +0 -40
  36. package/docs/.vitepress/cache/deps/chunk-FNDFPMRQ.js +0 -13131
  37. package/docs/.vitepress/cache/deps/chunk-FNDFPMRQ.js.map +0 -7
  38. package/docs/.vitepress/cache/deps/chunk-IOFLAFGL.js +0 -9719
  39. package/docs/.vitepress/cache/deps/chunk-IOFLAFGL.js.map +0 -7
  40. package/docs/.vitepress/cache/deps/package.json +0 -3
  41. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +0 -4483
  42. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +0 -7
  43. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +0 -583
  44. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +0 -7
  45. package/docs/.vitepress/cache/deps/vue.js +0 -347
  46. package/docs/.vitepress/cache/deps/vue.js.map +0 -7
  47. package/docs/.vitepress/config.ts +0 -32
@@ -605,8 +605,8 @@ function te(r, e) {
605
605
  return n;
606
606
  }
607
607
  export {
608
- ae as a,
609
- Ir as s,
608
+ Ir as a,
609
+ ae as s,
610
610
  te as u,
611
611
  oe as z
612
612
  };
@@ -1,10 +1,10 @@
1
- import { t as k, B as I, b as E, g as N } from "./toc-C6XLbDEA.js";
2
- import { s as F, d as H } from "./stylesheet-COz2MSt6.js";
3
- import { d as B, D as O, a as W, b as q, n as $, m as U } from "./lists-DpmgbDyt.js";
4
- import { l as j, p as K, D as z, b as _, B as T } from "./parse-JE_w0NNt.js";
5
- import { b as G, e as V, r as Z } from "./pipeline-CgbvBwNe.js";
1
+ import { t as k, B as I, j as E, k as N } from "./toc-BIj8uQ-W.js";
2
+ import { s as F, d as H } from "./stylesheet-EQFx9l5c.js";
3
+ import { d as B, D as O, a as W, b as q, n as $, m as j } from "./lists-BVCy5dMa.js";
4
+ import { l as U, p as K, D as z, b as _, B as T } from "./parse-DJZd-2A7.js";
5
+ import { b as G, d as V, r as Z } from "./pipeline-DKgBMmw1.js";
6
6
  function M(a, t) {
7
- return { root: j(a), display: t };
7
+ return { root: U(a), display: t };
8
8
  }
9
9
  function D(a, t) {
10
10
  return { ...K(a), display: t };
@@ -839,7 +839,7 @@ class P extends g {
839
839
  /** Register a custom list definition; reference it via .list(items,{listId:id}). */
840
840
  listDefinition(t, e) {
841
841
  const i = this.ctx.doc.lists ??= {};
842
- return "levels" in e ? i[t] = { id: t, levels: e.levels } : e.kind === "bullet" ? i[t] = q(t, e.char) : e.kind === "number" ? i[t] = $(t, e.format, e.suffix ?? ".") : i[t] = { ...U(), id: t }, this;
842
+ return "levels" in e ? i[t] = { id: t, levels: e.levels } : e.kind === "bullet" ? i[t] = q(t, e.char) : e.kind === "number" ? i[t] = $(t, e.format, e.suffix ?? ".") : i[t] = { ...j(), id: t }, this;
843
843
  }
844
844
  /** Register (or override) a builder-only table-style preset — reusable cell
845
845
  * formatting applied via .table(rows, { style: name }). Resolved to concrete
@@ -0,0 +1,376 @@
1
+ import { t as T } from "./toc-BIj8uQ-W.js";
2
+ function y(c) {
3
+ if (c.length === 0) return [];
4
+ const e = /* @__PURE__ */ new Map();
5
+ for (const s of c) {
6
+ let t = e.get(s.blockId);
7
+ t || (t = [], e.set(s.blockId, t)), t.push({ ...s });
8
+ }
9
+ const i = [];
10
+ for (const [s, t] of e) {
11
+ if (t.length === 0) continue;
12
+ const r = [];
13
+ for (const n of t) {
14
+ if (r.length === 0) {
15
+ r.push(n);
16
+ continue;
17
+ }
18
+ const o = r[r.length - 1];
19
+ if (o.action === "delete" && n.action === "insert" && o.offset === n.offset) {
20
+ o.action = "replace", o.toText = n.toText;
21
+ continue;
22
+ }
23
+ if (o.action === "replace" && n.action === "insert" && n.offset === o.offset + o.toText.length) {
24
+ o.toText += n.toText;
25
+ continue;
26
+ }
27
+ if (o.action === "insert" && n.action === "insert" && n.offset === o.offset + o.toText.length) {
28
+ o.toText += n.toText;
29
+ continue;
30
+ }
31
+ if (o.action === "delete" && n.action === "delete" && n.offset === o.offset) {
32
+ o.fromText += n.fromText;
33
+ continue;
34
+ }
35
+ if (o.action === "delete" && n.action === "delete" && n.offset + n.fromText.length === o.offset) {
36
+ o.offset = n.offset, o.fromText = n.fromText + o.fromText;
37
+ continue;
38
+ }
39
+ r.push(n);
40
+ }
41
+ for (const n of r)
42
+ n.action === "replace" && n.fromText === n.toText || n.action === "insert" && n.toText.length === 0 || n.action === "delete" && n.fromText.length === 0 || i.push({
43
+ action: n.action,
44
+ blockId: s,
45
+ offset: n.offset,
46
+ fromText: n.fromText,
47
+ toText: n.toText
48
+ });
49
+ }
50
+ return i;
51
+ }
52
+ function v(c, e) {
53
+ const i = new Map(Object.entries(e)), s = [];
54
+ for (const t of c)
55
+ if (t.type === "deleteRange") {
56
+ const r = i.get(t.blockId) ?? "", n = Math.max(0, Math.min(t.start, r.length)), o = Math.max(n, Math.min(t.end, r.length)), l = r.slice(n, o);
57
+ l.length > 0 && s.push({
58
+ action: "delete",
59
+ blockId: t.blockId,
60
+ offset: n,
61
+ fromText: l,
62
+ toText: ""
63
+ }), i.set(t.blockId, r.slice(0, n) + r.slice(o));
64
+ } else if (t.type === "insertText") {
65
+ const r = i.get(t.at.blockId) ?? "", n = Math.max(0, Math.min(t.at.offset, r.length));
66
+ t.text.length > 0 && s.push({
67
+ action: "insert",
68
+ blockId: t.at.blockId,
69
+ offset: n,
70
+ fromText: "",
71
+ toText: t.text
72
+ }), i.set(
73
+ t.at.blockId,
74
+ r.slice(0, n) + t.text + r.slice(n)
75
+ );
76
+ } else if (t.type === "insertRuns") {
77
+ const r = T(t.runs), n = i.get(t.at.blockId) ?? "", o = Math.max(0, Math.min(t.at.offset, n.length));
78
+ r.length > 0 && s.push({
79
+ action: "insert",
80
+ blockId: t.at.blockId,
81
+ offset: o,
82
+ fromText: "",
83
+ toText: r
84
+ }), i.set(
85
+ t.at.blockId,
86
+ n.slice(0, o) + r + n.slice(o)
87
+ );
88
+ } else if (t.type === "setRuns") {
89
+ const r = i.get(t.blockId) ?? "", n = T(t.runs);
90
+ r !== n && s.push({
91
+ action: "replace",
92
+ blockId: t.blockId,
93
+ offset: 0,
94
+ fromText: r,
95
+ toText: n
96
+ }), i.set(t.blockId, n);
97
+ } else if (t.type === "splitParagraph") {
98
+ const r = i.get(t.at.blockId) ?? "", n = Math.max(0, Math.min(t.at.offset, r.length)), o = r.slice(0, n), l = r.slice(n);
99
+ i.set(t.at.blockId, o), i.set(t.newBlockId, l);
100
+ } else if (t.type === "removeBlock") {
101
+ const r = i.get(t.blockId) ?? "";
102
+ r.length > 0 && s.push({
103
+ action: "delete",
104
+ blockId: t.blockId,
105
+ offset: 0,
106
+ fromText: r,
107
+ toText: ""
108
+ }), i.set(t.blockId, "");
109
+ }
110
+ return y(s);
111
+ }
112
+ function b(c, e, i, s = 0) {
113
+ if (c === e) return [];
114
+ let t = 0;
115
+ const r = Math.min(c.length, e.length);
116
+ for (; t < r && c[t] === e[t]; )
117
+ t++;
118
+ let n = 0;
119
+ const o = Math.min(c.length - t, e.length - t);
120
+ for (; n < o && c[c.length - 1 - n] === e[e.length - 1 - n]; )
121
+ n++;
122
+ const l = c.slice(t, c.length - n), f = e.slice(t, e.length - n), d = s + t;
123
+ return l.length > 0 && f.length === 0 ? [{ action: "delete", blockId: i, offset: d, fromText: l, toText: "" }] : l.length === 0 && f.length > 0 ? [{ action: "insert", blockId: i, offset: d, fromText: "", toText: f }] : l.length > 0 && f.length > 0 ? [{ action: "replace", blockId: i, offset: d, fromText: l, toText: f }] : [];
124
+ }
125
+ class S {
126
+ detail;
127
+ includeSelection;
128
+ handlers = /* @__PURE__ */ new Map();
129
+ anyHandlers = /* @__PURE__ */ new Set();
130
+ sink;
131
+ redact;
132
+ onError;
133
+ disposed = !1;
134
+ constructor(e = {}) {
135
+ this.detail = e.detail ?? "metadata", this.includeSelection = e.includeSelection ?? !1, this.sink = e.sink, this.redact = e.redact, this.onError = e.onError ?? ((i) => console.error("[kindy-editor:event]", i));
136
+ }
137
+ on(e, i, s = {}) {
138
+ if (this.disposed || s.signal?.aborted) return () => {
139
+ };
140
+ let t = this.handlers.get(e);
141
+ t || this.handlers.set(e, t = /* @__PURE__ */ new Set()), t.add(i);
142
+ const r = () => {
143
+ t?.delete(i), t?.size === 0 && this.handlers.delete(e);
144
+ };
145
+ return s.signal?.addEventListener("abort", r, { once: !0 }), r;
146
+ }
147
+ onAny(e, i = {}) {
148
+ if (this.disposed || i.signal?.aborted) return () => {
149
+ };
150
+ this.anyHandlers.add(e);
151
+ const s = () => {
152
+ this.anyHandlers.delete(e);
153
+ };
154
+ return i.signal?.addEventListener("abort", s, { once: !0 }), s;
155
+ }
156
+ off(e, i) {
157
+ this.handlers.get(e)?.delete(i);
158
+ }
159
+ /** Called by the editor runtime after state is already consistent. Public only
160
+ * for custom bridges; normal integrations subscribe with on/onAny. */
161
+ dispatch(e) {
162
+ if (this.disposed) return;
163
+ const i = this.redact ? this.redact(e) : e;
164
+ if (i) {
165
+ for (const s of this.handlers.get(i.type) ?? []) this.safeCall(s, i);
166
+ for (const s of this.anyHandlers) this.safeCall(s, i);
167
+ if (this.sink)
168
+ try {
169
+ Promise.resolve(this.sink(i)).catch((s) => this.reportError(s, i));
170
+ } catch (s) {
171
+ this.reportError(s, i);
172
+ }
173
+ }
174
+ }
175
+ destroy() {
176
+ this.disposed = !0, this.handlers.clear(), this.anyHandlers.clear();
177
+ }
178
+ safeCall(e, i) {
179
+ try {
180
+ e(i);
181
+ } catch (s) {
182
+ this.reportError(s, i);
183
+ }
184
+ }
185
+ reportError(e, i) {
186
+ try {
187
+ this.onError(e, i);
188
+ } catch (s) {
189
+ console.error("[kindy-editor:event:onError]", s);
190
+ }
191
+ }
192
+ }
193
+ function w(c) {
194
+ const e = c.fetch ?? globalThis.fetch;
195
+ if (!e) throw new Error("createHttpEventSink requires fetch");
196
+ const i = Math.max(1, c.batchSize ?? 25), s = Math.max(10, c.flushIntervalMs ?? 1e3), t = Math.max(1, c.maxAttempts ?? 3);
197
+ let r = [], n = null, o = Promise.resolve(), l = !1;
198
+ const f = () => {
199
+ n && clearTimeout(n), n = null;
200
+ }, d = async () => {
201
+ const a = typeof c.headers == "function" ? await c.headers() : c.headers, h = new Headers(a);
202
+ return h.has("content-type") || h.set("content-type", "application/json"), h;
203
+ }, p = async (a) => {
204
+ let h;
205
+ for (let g = 1; g <= t; g++)
206
+ try {
207
+ const m = await e(c.endpoint, {
208
+ method: "POST",
209
+ headers: await d(),
210
+ body: JSON.stringify({ schemaVersion: a[0]?.schemaVersion ?? "1.0", events: a })
211
+ });
212
+ if (!m.ok) throw new Error(`event sink returned HTTP ${m.status}`);
213
+ return;
214
+ } catch (m) {
215
+ h = m, g < t && await new Promise((I) => setTimeout(I, 100 * 2 ** (g - 1)));
216
+ }
217
+ c.onDeliveryError?.(h, a);
218
+ }, u = async () => {
219
+ if (f(), r.length === 0) return o;
220
+ const a = r;
221
+ r = [], o = o.then(() => p(a)), await o;
222
+ }, x = (a) => {
223
+ l || c.eventTypes && !c.eventTypes.includes(a.type) || (r.push(a), r.length >= i ? u() : n || (n = setTimeout(() => void u(), s)));
224
+ };
225
+ return x.flush = u, x.destroy = async () => {
226
+ l = !0, await u();
227
+ }, x;
228
+ }
229
+ class k {
230
+ idleMs;
231
+ selectionJumpThreshold;
232
+ constructor(e = {}) {
233
+ this.idleMs = Math.max(100, e.idleMs ?? 1e3), this.selectionJumpThreshold = Math.max(1, e.selectionJumpThreshold ?? 2);
234
+ }
235
+ /**
236
+ * Evaluates if a selection movement constitutes a boundary (e.g. jumped to another block
237
+ * or moved far away from the active typing position).
238
+ */
239
+ shouldCommitOnSelectionChange(e, i, s, t) {
240
+ return !e || s === null || t === null ? !1 : e !== s || i !== null && Math.abs(t - i) > this.selectionJumpThreshold;
241
+ }
242
+ }
243
+ class B {
244
+ policy;
245
+ emit;
246
+ getVersion;
247
+ idGenerator;
248
+ currentSession = null;
249
+ idleTimer = null;
250
+ disposed = !1;
251
+ nextGroupId = 1;
252
+ constructor(e) {
253
+ this.policy = e.policy instanceof k ? e.policy : new k({
254
+ ...typeof e.idleMs == "number" ? { idleMs: e.idleMs } : {},
255
+ ...e.policy
256
+ }), this.emit = e.emit, this.getVersion = e.getVersion ?? (() => 0), this.idGenerator = e.idGenerator ?? (() => `chg-${Date.now()}-${this.nextGroupId++}`);
257
+ }
258
+ /**
259
+ * Tracks a raw applied change. Starts a new session or extends the active session.
260
+ */
261
+ trackChange(e) {
262
+ if (this.disposed) return;
263
+ this.currentSession && this.currentSession.origin !== e.origin && this.flush("origin-change");
264
+ const i = e.version ?? this.getVersion();
265
+ if (!this.currentSession) {
266
+ const t = this.getVersion(), r = e.version ?? t;
267
+ this.currentSession = {
268
+ changeGroupId: this.idGenerator(),
269
+ origin: e.origin,
270
+ ...e.intent !== void 0 ? { intent: e.intent } : {},
271
+ beforeVersion: t,
272
+ afterVersion: r,
273
+ lastTransactionId: e.transactionId,
274
+ initialBlockTexts: /* @__PURE__ */ new Map(),
275
+ currentBlockTexts: /* @__PURE__ */ new Map(),
276
+ diffs: [],
277
+ activeBlockId: e.selectionAfter?.focus.blockId ?? null,
278
+ lastOffset: e.selectionAfter?.focus.offset ?? null
279
+ };
280
+ }
281
+ const s = this.currentSession;
282
+ if (s) {
283
+ s.afterVersion = i, s.lastTransactionId = e.transactionId, e.intent !== void 0 && s.intent === void 0 && (s.intent = e.intent);
284
+ for (const t of e.affectedBlockIds)
285
+ if (!s.initialBlockTexts.has(t)) {
286
+ const r = e.blockTextBefore?.[t] ?? "";
287
+ s.initialBlockTexts.set(t, r), s.currentBlockTexts.set(t, r);
288
+ }
289
+ if (this.applyOpsToCurrentTexts(s.currentBlockTexts, e.ops), e.textDiffs && e.textDiffs.length > 0 && s.diffs.push(...e.textDiffs), e.selectionAfter && (s.activeBlockId = e.selectionAfter.focus.blockId, s.lastOffset = e.selectionAfter.focus.offset), e.origin === "paste" || e.origin === "command") {
290
+ this.flush("explicit");
291
+ return;
292
+ }
293
+ this.restartIdleTimer();
294
+ }
295
+ }
296
+ /**
297
+ * Signals a semantic boundary from the editor environment (blur, save, selection change, etc.).
298
+ */
299
+ notifyBoundary(e, i) {
300
+ if (!(this.disposed || !this.currentSession)) {
301
+ if (e === "selection-jump") {
302
+ this.policy.shouldCommitOnSelectionChange(
303
+ this.currentSession.activeBlockId,
304
+ this.currentSession.lastOffset,
305
+ i?.newBlockId ?? null,
306
+ i?.newOffset ?? null
307
+ ) && this.flush("selection-jump");
308
+ return;
309
+ }
310
+ this.flush(e);
311
+ }
312
+ }
313
+ /**
314
+ * Flushes and commits the active session if one exists and contains non-trivial changes.
315
+ */
316
+ flush(e) {
317
+ this.clearIdleTimer();
318
+ const i = this.currentSession;
319
+ if (!i) return;
320
+ this.currentSession = null;
321
+ const s = [];
322
+ for (const [t, r] of i.initialBlockTexts) {
323
+ const n = i.currentBlockTexts.get(t) ?? r;
324
+ if (r !== n) {
325
+ const o = b(r, n, t);
326
+ s.push(...o);
327
+ }
328
+ }
329
+ s.length !== 0 && this.emit({
330
+ transactionId: i.lastTransactionId,
331
+ changeGroupId: i.changeGroupId,
332
+ beforeVersion: i.beforeVersion,
333
+ afterVersion: i.afterVersion,
334
+ origin: i.origin,
335
+ textDiffs: s,
336
+ ...i.intent ? { intent: i.intent } : {},
337
+ affectedBlockIds: Array.from(i.initialBlockTexts.keys())
338
+ });
339
+ }
340
+ destroy() {
341
+ this.disposed || (this.flush("destroy"), this.disposed = !0);
342
+ }
343
+ applyOpsToCurrentTexts(e, i) {
344
+ for (const s of i)
345
+ if (s.type === "deleteRange") {
346
+ const t = e.get(s.blockId) ?? "", r = Math.max(0, Math.min(s.start, t.length)), n = Math.max(r, Math.min(s.end, t.length));
347
+ e.set(s.blockId, t.slice(0, r) + t.slice(n));
348
+ } else if (s.type === "insertText") {
349
+ const t = e.get(s.at.blockId) ?? "", r = Math.max(0, Math.min(s.at.offset, t.length));
350
+ e.set(s.at.blockId, t.slice(0, r) + s.text + t.slice(r));
351
+ } else if (s.type === "insertRuns") {
352
+ const t = T(s.runs), r = e.get(s.at.blockId) ?? "", n = Math.max(0, Math.min(s.at.offset, r.length));
353
+ e.set(s.at.blockId, r.slice(0, n) + t + r.slice(n));
354
+ } else if (s.type === "setRuns")
355
+ e.set(s.blockId, T(s.runs));
356
+ else if (s.type === "splitParagraph") {
357
+ const t = e.get(s.at.blockId) ?? "", r = Math.max(0, Math.min(s.at.offset, t.length));
358
+ e.set(s.at.blockId, t.slice(0, r)), e.set(s.newBlockId, t.slice(r));
359
+ } else s.type === "removeBlock" && e.set(s.blockId, "");
360
+ }
361
+ restartIdleTimer() {
362
+ this.clearIdleTimer(), this.idleTimer = setTimeout(() => {
363
+ this.flush("idle");
364
+ }, this.policy.idleMs);
365
+ }
366
+ clearIdleTimer() {
367
+ this.idleTimer && (clearTimeout(this.idleTimer), this.idleTimer = null);
368
+ }
369
+ }
370
+ export {
371
+ B as C,
372
+ S as E,
373
+ k as a,
374
+ v as b,
375
+ w as c
376
+ };