quoin-editor 1.0.0 → 1.0.2

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 (213) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/dist/ai.cjs +135 -94
  3. package/dist/ai.cjs.map +1 -1
  4. package/dist/ai.d.cts +1 -1
  5. package/dist/ai.d.ts +1 -1
  6. package/dist/ai.js +62 -21
  7. package/dist/ai.js.map +1 -1
  8. package/dist/catalogue.cjs +25 -25
  9. package/dist/catalogue.d.cts +6 -6
  10. package/dist/catalogue.d.ts +6 -6
  11. package/dist/catalogue.js +17 -17
  12. package/dist/{chunk-ND5XJVK2.cjs → chunk-4SLJNZSM.cjs} +27 -23
  13. package/dist/chunk-4SLJNZSM.cjs.map +1 -0
  14. package/dist/{chunk-LCQSG4M6.js → chunk-4XFXB37X.js} +22 -18
  15. package/dist/chunk-4XFXB37X.js.map +1 -0
  16. package/dist/{chunk-AEJXZBVR.cjs → chunk-5MAYUGTE.cjs} +110 -103
  17. package/dist/chunk-5MAYUGTE.cjs.map +1 -0
  18. package/dist/{chunk-JDPTZUBW.js → chunk-623AOJM2.js} +4 -4
  19. package/dist/chunk-6NULZPVC.js +374 -0
  20. package/dist/chunk-6NULZPVC.js.map +1 -0
  21. package/dist/{chunk-2QCRZ7OL.cjs → chunk-6V6GGBDK.cjs} +12 -11
  22. package/dist/{chunk-2QCRZ7OL.cjs.map → chunk-6V6GGBDK.cjs.map} +1 -1
  23. package/dist/{chunk-WXMYDXPN.cjs → chunk-73653CJ4.cjs} +4 -3
  24. package/dist/chunk-73653CJ4.cjs.map +1 -0
  25. package/dist/{chunk-47MLKSI2.js → chunk-ADSJ42DO.js} +6 -6
  26. package/dist/{chunk-PWUEPDA3.cjs → chunk-AUOEM3SF.cjs} +44 -44
  27. package/dist/{chunk-PWUEPDA3.cjs.map → chunk-AUOEM3SF.cjs.map} +1 -1
  28. package/dist/{chunk-WQHV3MRE.cjs → chunk-BQANU5BH.cjs} +12 -12
  29. package/dist/{chunk-WQHV3MRE.cjs.map → chunk-BQANU5BH.cjs.map} +1 -1
  30. package/dist/{chunk-KXOBZGQO.js → chunk-C23RQVRK.js} +21 -14
  31. package/dist/chunk-C23RQVRK.js.map +1 -0
  32. package/dist/{chunk-2VDK27IF.cjs → chunk-CW3AFJBR.cjs} +312 -342
  33. package/dist/chunk-CW3AFJBR.cjs.map +1 -0
  34. package/dist/{chunk-MQ2XQ4MX.js → chunk-DUE3HCZD.js} +6 -6
  35. package/dist/chunk-DUE3HCZD.js.map +1 -0
  36. package/dist/{chunk-OMOBMXD5.cjs → chunk-EH5KXQXY.cjs} +7 -2
  37. package/dist/chunk-EH5KXQXY.cjs.map +1 -0
  38. package/dist/{chunk-ZS2WA357.js → chunk-EPARJI4V.js} +147 -129
  39. package/dist/chunk-EPARJI4V.js.map +1 -0
  40. package/dist/{chunk-HZSSEYJS.cjs → chunk-FDRUAL3Z.cjs} +30 -30
  41. package/dist/{chunk-HZSSEYJS.cjs.map → chunk-FDRUAL3Z.cjs.map} +1 -1
  42. package/dist/{chunk-T7SW6OWV.js → chunk-IQBMAE3F.js} +5 -5
  43. package/dist/{chunk-RUDWMKYX.js → chunk-JHQUHFLX.js} +8 -8
  44. package/dist/{chunk-HELJTLNC.cjs → chunk-KUYZMSMF.cjs} +12 -12
  45. package/dist/chunk-KUYZMSMF.cjs.map +1 -0
  46. package/dist/chunk-LE5XMIFJ.cjs +14 -0
  47. package/dist/chunk-LE5XMIFJ.cjs.map +1 -0
  48. package/dist/{chunk-EL2OEJQC.cjs → chunk-LLTEGXWZ.cjs} +56 -56
  49. package/dist/{chunk-EL2OEJQC.cjs.map → chunk-LLTEGXWZ.cjs.map} +1 -1
  50. package/dist/chunk-MQUCCSWG.js +14 -0
  51. package/dist/chunk-MQUCCSWG.js.map +1 -0
  52. package/dist/{chunk-NNDYYEW5.js → chunk-N4FGA3H4.js} +5 -5
  53. package/dist/{chunk-ZHOSSWUM.js → chunk-NEZJ7ZP5.js} +4 -3
  54. package/dist/chunk-NEZJ7ZP5.js.map +1 -0
  55. package/dist/{chunk-XEBWC7ZL.js → chunk-O4Z2WMFF.js} +7 -2
  56. package/dist/chunk-O4Z2WMFF.js.map +1 -0
  57. package/dist/{chunk-HJIQT3S5.js → chunk-OBMBSU2S.js} +100 -84
  58. package/dist/chunk-OBMBSU2S.js.map +1 -0
  59. package/dist/{chunk-KAVU6T6J.js → chunk-OSHZQR3W.js} +5 -5
  60. package/dist/{chunk-GTTPVJSD.cjs → chunk-P6KYXFZC.cjs} +265 -247
  61. package/dist/chunk-P6KYXFZC.cjs.map +1 -0
  62. package/dist/{chunk-CDELOHDY.cjs → chunk-R2BLBV43.cjs} +23 -23
  63. package/dist/{chunk-CDELOHDY.cjs.map → chunk-R2BLBV43.cjs.map} +1 -1
  64. package/dist/{chunk-NOKWNK2O.js → chunk-RJRX34BZ.js} +3 -2
  65. package/dist/{chunk-ZGZEJCRV.js → chunk-T43RZTUT.js} +166 -196
  66. package/dist/chunk-T43RZTUT.js.map +1 -0
  67. package/dist/chunk-TLGX43P6.cjs +374 -0
  68. package/dist/chunk-TLGX43P6.cjs.map +1 -0
  69. package/dist/{chunk-POBM7MGR.js → chunk-U3LOLYAU.js} +2 -2
  70. package/dist/{chunk-RDG4VI6E.cjs → chunk-UEKXVCKC.cjs} +103 -93
  71. package/dist/chunk-UEKXVCKC.cjs.map +1 -0
  72. package/dist/{chunk-PMWCQSQX.js → chunk-VCLL5C7J.js} +5 -5
  73. package/dist/{chunk-SG37UBDO.js → chunk-VRS6WCEK.js} +20 -10
  74. package/dist/chunk-VRS6WCEK.js.map +1 -0
  75. package/dist/{chunk-ZC24WB7Y.cjs → chunk-WEYDDIBQ.cjs} +14 -14
  76. package/dist/{chunk-ZC24WB7Y.cjs.map → chunk-WEYDDIBQ.cjs.map} +1 -1
  77. package/dist/{chunk-5DNCCN6X.cjs → chunk-X4HDKFW5.cjs} +27 -27
  78. package/dist/{chunk-5DNCCN6X.cjs.map → chunk-X4HDKFW5.cjs.map} +1 -1
  79. package/dist/{chunk-SLVDAHHK.cjs → chunk-X4P4TQXH.cjs} +5 -5
  80. package/dist/{chunk-SLVDAHHK.cjs.map → chunk-X4P4TQXH.cjs.map} +1 -1
  81. package/dist/{chunk-GLLXHMH2.cjs → chunk-XA3UEJIW.cjs} +3 -3
  82. package/dist/{chunk-GLLXHMH2.cjs.map → chunk-XA3UEJIW.cjs.map} +1 -1
  83. package/dist/{chunk-K574XHMM.js → chunk-YBMUEEM5.js} +2 -2
  84. package/dist/{chunk-PZ4GT5JO.cjs → chunk-ZKVOS57Q.cjs} +316 -300
  85. package/dist/chunk-ZKVOS57Q.cjs.map +1 -0
  86. package/dist/comments.cjs +113 -98
  87. package/dist/comments.cjs.map +1 -1
  88. package/dist/comments.d.cts +6 -1
  89. package/dist/comments.d.ts +6 -1
  90. package/dist/comments.js +32 -17
  91. package/dist/comments.js.map +1 -1
  92. package/dist/diff.cjs +44 -40
  93. package/dist/diff.cjs.map +1 -1
  94. package/dist/diff.js +17 -13
  95. package/dist/diff.js.map +1 -1
  96. package/dist/docx.cjs +60 -40
  97. package/dist/docx.cjs.map +1 -1
  98. package/dist/docx.d.cts +6 -0
  99. package/dist/docx.d.ts +6 -0
  100. package/dist/docx.js +32 -12
  101. package/dist/docx.js.map +1 -1
  102. package/dist/embed.cjs +9 -9
  103. package/dist/embed.d.cts +1 -1
  104. package/dist/embed.d.ts +1 -1
  105. package/dist/embed.js +8 -8
  106. package/dist/{emoji-extension-DpQ43HjE.d.ts → emoji-extension-CmPlRssm.d.ts} +1 -1
  107. package/dist/{emoji-extension-C12gDPm6.d.cts → emoji-extension-zJ6F7hW8.d.cts} +1 -1
  108. package/dist/emoji.cjs +8 -8
  109. package/dist/emoji.d.cts +3 -3
  110. package/dist/emoji.d.ts +3 -3
  111. package/dist/emoji.js +7 -7
  112. package/dist/engine.cjs +4 -4
  113. package/dist/engine.d.cts +2 -2
  114. package/dist/engine.d.ts +2 -2
  115. package/dist/engine.js +3 -3
  116. package/dist/{find-extension-_sbZEt3R.d.cts → find-extension-BcRyE9K4.d.cts} +1 -1
  117. package/dist/{find-extension-DKqLLSuP.d.ts → find-extension-CmFehyul.d.ts} +1 -1
  118. package/dist/find.cjs +8 -8
  119. package/dist/find.d.cts +2 -2
  120. package/dist/find.d.ts +2 -2
  121. package/dist/find.js +7 -7
  122. package/dist/headless.cjs +5 -5
  123. package/dist/headless.d.cts +4 -4
  124. package/dist/headless.d.ts +4 -4
  125. package/dist/headless.js +4 -4
  126. package/dist/{index-CgD72kHB.d.cts → index-CFPmCee4.d.cts} +5 -2
  127. package/dist/{index-DNYbTK3w.d.ts → index-DiCGV60d.d.ts} +5 -2
  128. package/dist/index.cjs +7 -7
  129. package/dist/index.d.cts +4 -4
  130. package/dist/index.d.ts +4 -4
  131. package/dist/index.js +6 -6
  132. package/dist/math.cjs +10 -10
  133. package/dist/math.d.cts +1 -1
  134. package/dist/math.d.ts +1 -1
  135. package/dist/math.js +9 -9
  136. package/dist/mention.cjs +10 -10
  137. package/dist/mention.d.cts +1 -1
  138. package/dist/mention.d.ts +1 -1
  139. package/dist/mention.js +9 -9
  140. package/dist/presence.cjs +98 -104
  141. package/dist/presence.cjs.map +1 -1
  142. package/dist/presence.d.cts +2 -2
  143. package/dist/presence.d.ts +2 -2
  144. package/dist/presence.js +66 -72
  145. package/dist/presence.js.map +1 -1
  146. package/dist/{stats-extension-Bly88uio.d.ts → stats-extension-DisOEbbI.d.ts} +1 -1
  147. package/dist/{stats-extension-CJPijvUb.d.cts → stats-extension-Dt1lgP3m.d.cts} +1 -1
  148. package/dist/stats.cjs +9 -9
  149. package/dist/stats.d.cts +3 -3
  150. package/dist/stats.d.ts +3 -3
  151. package/dist/stats.js +8 -8
  152. package/dist/styles.css +1 -1
  153. package/dist/{table-extension-Dzf4k6hI.d.ts → table-extension-BTMJnT7J.d.ts} +1 -1
  154. package/dist/{table-extension-BTLxFy2S.d.cts → table-extension-DxZz3jqp.d.cts} +1 -1
  155. package/dist/table.cjs +8 -8
  156. package/dist/table.d.cts +2 -2
  157. package/dist/table.d.ts +2 -2
  158. package/dist/table.js +7 -7
  159. package/dist/{toc-extension-DWm5alVj.d.ts → toc-extension-CR9U-l6j.d.ts} +1 -1
  160. package/dist/{toc-extension-B3-s6h2x.d.cts → toc-extension-DGHywOBv.d.cts} +1 -1
  161. package/dist/toc.cjs +8 -8
  162. package/dist/toc.d.cts +2 -2
  163. package/dist/toc.d.ts +2 -2
  164. package/dist/toc.js +7 -7
  165. package/dist/{types-a1CRBlEh.d.ts → types-C6_QkXzy.d.ts} +1 -9
  166. package/dist/{types-Cz7XJLaK.d.cts → types-CJ7Gq3GX.d.cts} +1 -9
  167. package/dist/{view-controller-DSHw0ltQ.d.cts → view-controller-BD1KwYfE.d.cts} +6 -19
  168. package/dist/{view-controller-UbpzblGl.d.ts → view-controller-y4cb60ue.d.ts} +6 -19
  169. package/dist/view.cjs +6 -6
  170. package/dist/view.js +3 -3
  171. package/dist/yjs.cjs +302 -412
  172. package/dist/yjs.cjs.map +1 -1
  173. package/dist/yjs.d.cts +3 -3
  174. package/dist/yjs.d.ts +3 -3
  175. package/dist/yjs.js +211 -321
  176. package/dist/yjs.js.map +1 -1
  177. package/package.json +1 -1
  178. package/dist/chunk-2VDK27IF.cjs.map +0 -1
  179. package/dist/chunk-AEJXZBVR.cjs.map +0 -1
  180. package/dist/chunk-E75EHRPA.cjs +0 -175
  181. package/dist/chunk-E75EHRPA.cjs.map +0 -1
  182. package/dist/chunk-GTTPVJSD.cjs.map +0 -1
  183. package/dist/chunk-HELJTLNC.cjs.map +0 -1
  184. package/dist/chunk-HJIQT3S5.js.map +0 -1
  185. package/dist/chunk-JEIFJHEI.js +0 -14
  186. package/dist/chunk-JEIFJHEI.js.map +0 -1
  187. package/dist/chunk-KXOBZGQO.js.map +0 -1
  188. package/dist/chunk-LCQSG4M6.js.map +0 -1
  189. package/dist/chunk-MQ2XQ4MX.js.map +0 -1
  190. package/dist/chunk-ND5XJVK2.cjs.map +0 -1
  191. package/dist/chunk-OMOBMXD5.cjs.map +0 -1
  192. package/dist/chunk-PZ4GT5JO.cjs.map +0 -1
  193. package/dist/chunk-QAW5NH6S.cjs +0 -14
  194. package/dist/chunk-QAW5NH6S.cjs.map +0 -1
  195. package/dist/chunk-RDG4VI6E.cjs.map +0 -1
  196. package/dist/chunk-SG37UBDO.js.map +0 -1
  197. package/dist/chunk-TC4DARU2.js +0 -175
  198. package/dist/chunk-TC4DARU2.js.map +0 -1
  199. package/dist/chunk-WXMYDXPN.cjs.map +0 -1
  200. package/dist/chunk-XEBWC7ZL.js.map +0 -1
  201. package/dist/chunk-ZGZEJCRV.js.map +0 -1
  202. package/dist/chunk-ZHOSSWUM.js.map +0 -1
  203. package/dist/chunk-ZS2WA357.js.map +0 -1
  204. /package/dist/{chunk-JDPTZUBW.js.map → chunk-623AOJM2.js.map} +0 -0
  205. /package/dist/{chunk-47MLKSI2.js.map → chunk-ADSJ42DO.js.map} +0 -0
  206. /package/dist/{chunk-T7SW6OWV.js.map → chunk-IQBMAE3F.js.map} +0 -0
  207. /package/dist/{chunk-RUDWMKYX.js.map → chunk-JHQUHFLX.js.map} +0 -0
  208. /package/dist/{chunk-NNDYYEW5.js.map → chunk-N4FGA3H4.js.map} +0 -0
  209. /package/dist/{chunk-KAVU6T6J.js.map → chunk-OSHZQR3W.js.map} +0 -0
  210. /package/dist/{chunk-NOKWNK2O.js.map → chunk-RJRX34BZ.js.map} +0 -0
  211. /package/dist/{chunk-POBM7MGR.js.map → chunk-U3LOLYAU.js.map} +0 -0
  212. /package/dist/{chunk-PMWCQSQX.js.map → chunk-VCLL5C7J.js.map} +0 -0
  213. /package/dist/{chunk-K574XHMM.js.map → chunk-YBMUEEM5.js.map} +0 -0
package/dist/yjs.js CHANGED
@@ -1,172 +1,66 @@
1
1
  import {
2
+ applyRemote,
3
+ attrsMap,
2
4
  cleanEntry,
3
5
  createLayout,
6
+ definedEntries,
7
+ deleteText,
4
8
  emptySpan,
5
9
  grow,
6
10
  holdBinding,
7
11
  holdSelection,
8
12
  indexOf,
13
+ inlineOfOps,
14
+ insertInline,
15
+ isAtomEmbed,
16
+ markAttribute,
17
+ markerOf,
9
18
  offsetIn,
10
19
  piecesOf,
11
20
  placeEntries,
12
21
  pointOf,
22
+ readMarker,
23
+ regionNameOf,
13
24
  regionOf,
25
+ regionStart,
14
26
  restoreSelection,
27
+ sharedChange,
15
28
  spanAt,
16
29
  spanStart,
17
- textLength
18
- } from "./chunk-TC4DARU2.js";
30
+ textLength,
31
+ textSteps,
32
+ writeBlock,
33
+ writeBlocks
34
+ } from "./chunk-6NULZPVC.js";
19
35
  import {
20
- HISTORY_GROUP,
21
36
  HISTORY_PROVIDER,
22
- addMarkStep,
23
37
  createPluginKey,
24
38
  defineExtension,
25
39
  getPluginState,
40
+ groupOf,
26
41
  joinBlocksStep,
27
- removeMarkStep,
28
42
  replaceBlockStep,
29
43
  replaceDocStep,
30
- replaceInlineStep,
31
44
  sameDoc,
32
- sameSelection,
33
45
  setAttrsStep,
34
46
  setIndentStep,
35
- splitBlockStep,
36
- validateSelection
37
- } from "./chunk-HJIQT3S5.js";
47
+ splitBlockStep
48
+ } from "./chunk-OBMBSU2S.js";
38
49
  import {
39
50
  sameValue
40
- } from "./chunk-NOKWNK2O.js";
51
+ } from "./chunk-RJRX34BZ.js";
41
52
  import {
42
- atom,
43
53
  blockById,
44
54
  createDoc,
45
55
  equalInline,
46
56
  equalNode,
47
57
  inlineLength,
48
- markKey,
49
- nodeLength,
50
- normalizeInline,
51
58
  sliceInline,
52
59
  text
53
- } from "./chunk-LCQSG4M6.js";
54
-
55
- // src/engine/collab/apply-remote.ts
56
- function applyRemote(editor, steps, selectionHint) {
57
- const tr = editor.createTransaction().setOrigin("remote").setMeta("addToHistory", false);
58
- for (const step of steps) tr.step(step);
59
- if (selectionHint && sameSelection(validateSelection(tr.doc, editor.schema, selectionHint), selectionHint)) {
60
- tr.setSelection(selectionHint);
61
- }
62
- editor.dispatch(tr);
63
- }
64
-
65
- // src/yjs/local-to-yjs.ts
66
- import * as Y4 from "yjs";
67
-
68
- // src/yjs/doc-shape.ts
69
- import * as Y from "yjs";
70
-
71
- // src/yjs/marks-codec.ts
72
- var ESCAPE = "$";
73
- var escapeKey = (key) => key in Object.prototype || key.startsWith(ESCAPE) ? ESCAPE + key : key;
74
- var unescapeKey = (key) => key.startsWith(ESCAPE) ? key.slice(1) : key;
75
- var onlyString = (attrs, key) => Object.keys(attrs).length === 1 && Object.hasOwn(attrs, key) && typeof attrs[key] === "string";
76
- function markAttribute(mark) {
77
- const key = markKey(mark);
78
- const { attrs } = mark;
79
- const stacked = key !== mark.type;
80
- if (attrs === void 0) return [escapeKey(key), !stacked];
81
- if (stacked && onlyString(attrs, "id")) return [escapeKey(key), true];
82
- if (onlyString(attrs, mark.type)) return [escapeKey(key), attrs[mark.type]];
83
- return [escapeKey(key), attrs];
84
- }
85
- function stackedType(key) {
86
- const colon = key.indexOf(":");
87
- if (colon < 1) return null;
88
- const type = key.slice(0, colon);
89
- const id = key.slice(colon + 1);
90
- return markKey({ type, attrs: { id } }) === key ? [type, id] : null;
91
- }
92
- function markFromAttribute(attribute, value) {
93
- const key = unescapeKey(attribute);
94
- const stacked = stackedType(key);
95
- const type = stacked?.[0] ?? key;
96
- if (value === true) return stacked === null ? { type } : { type, attrs: { id: stacked[1] } };
97
- if (value === false) return { type };
98
- if (typeof value === "string") return { type, attrs: { [type]: value } };
99
- return { type, attrs: value };
100
- }
101
- var marksToAttributes = (marks) => Object.fromEntries(marks.map(markAttribute));
102
- var attributesToMarks = (attributes = {}) => Object.entries(attributes).map(([key, value]) => markFromAttribute(key, value));
103
-
104
- // src/yjs/inline-codec.ts
105
- var inlineOps = (inline) => inline.map((node) => ({
106
- insert: node.kind === "text" ? node.text : { atom: node.type, attrs: node.attrs },
107
- attributes: marksToAttributes(node.marks)
108
- }));
109
- function insertInline(target, at, inline) {
110
- let offset = at;
111
- for (const node of inline) {
112
- const attributes = marksToAttributes(node.marks);
113
- if (node.kind === "text") target.insert(offset, node.text, attributes);
114
- else target.insertEmbed(offset, { atom: node.type, attrs: node.attrs }, attributes);
115
- offset += nodeLength(node);
116
- }
117
- }
118
- function nodeOf({ insert, attributes }) {
119
- const marks = attributesToMarks(attributes);
120
- return typeof insert === "string" ? text(insert, marks) : atom(insert.atom, insert.attrs, marks);
121
- }
122
- var inlineOfOps = (ops) => normalizeInline(ops.map(nodeOf));
123
-
124
- // src/yjs/doc-shape.ts
125
- var deleteText = (text2, at, length) => text2.applyDelta(at > 0 ? [{ retain: at }, { delete: length }] : [{ delete: length }]);
126
- var regionStart = (name) => ({ r: name });
127
- var isPlainObject = (value) => typeof value === "object" && value !== null && !(value instanceof Y.AbstractType);
128
- var regionNameOf = (embed) => isPlainObject(embed) && typeof embed.r === "string" && embed.atom === void 0 ? embed.r : null;
129
- var isAtomEmbed = (embed) => isPlainObject(embed) && typeof embed.atom === "string" && isPlainObject(embed.attrs);
130
- var definedEntries = (attrs) => Object.entries(attrs).filter(([, value]) => value !== void 0);
131
- function markerOf(block) {
132
- return new Y.Map([
133
- ["id", block.id],
134
- ["type", block.type],
135
- ["indent", block.indent],
136
- ["attrs", new Y.Map(definedEntries(block.attrs))]
137
- ]);
138
- }
139
- function readMarker(map) {
140
- const [id, type, indent, attrs] = ["id", "type", "indent", "attrs"].map((key) => map.get(key));
141
- if (typeof id !== "string") return null;
142
- return {
143
- id,
144
- type: typeof type === "string" ? type : "",
145
- indent: typeof indent === "number" ? indent : 0,
146
- attrs: attrs instanceof Y.Map ? attrs : null
147
- };
148
- }
149
- function blockOps(block, map, open) {
150
- const ops = [{ insert: map, attributes: {} }];
151
- for (const [name, inline] of Object.entries(block.regions)) {
152
- ops.push({ insert: regionStart(name), attributes: {} });
153
- if (name === open) break;
154
- ops.push(...inlineOps(inline));
155
- }
156
- return ops;
157
- }
158
- var writeOps = (text2, at, ops) => text2.applyDelta(at > 0 ? [{ retain: at }, ...ops] : ops);
159
- function writeBlock(text2, at, block, map, open) {
160
- writeOps(text2, at, blockOps(block, map, open));
161
- }
162
- function writeBlocks(text2, at, blocks) {
163
- const maps = blocks.map(markerOf);
164
- writeOps(text2, at, blocks.flatMap((block, i) => blockOps(block, maps[i])));
165
- return maps;
166
- }
60
+ } from "./chunk-4XFXB37X.js";
167
61
 
168
62
  // src/yjs/read-shared.ts
169
- import * as Y2 from "yjs";
63
+ import * as Y from "yjs";
170
64
 
171
65
  // src/yjs/required-regions.ts
172
66
  var noRequiredRegions = () => [];
@@ -195,7 +89,6 @@ function reader(required) {
195
89
  let entry = null;
196
90
  let open = null;
197
91
  let stray = null;
198
- let clean = true;
199
92
  const segFor = (region2, host, at, ops = []) => {
200
93
  const seg = { host, region: region2, at, length: 0 };
201
94
  host.segs.push(seg);
@@ -212,7 +105,6 @@ function reader(required) {
212
105
  open.length += length;
213
106
  held2.get(open).push(op);
214
107
  } else if (span.index === 0 || span.entry !== null) {
215
- clean = false;
216
108
  if (stray === null) {
217
109
  stray = { host: span, at: span.length, length: 0, ops: [], after: order[order.length - 1] ?? null };
218
110
  strays.push(stray);
@@ -233,25 +125,26 @@ function reader(required) {
233
125
  span.entry = entry;
234
126
  entries.set(entry.id, entry);
235
127
  markers.set(entry, fields);
236
- } else {
237
- clean = false;
238
- if (fields !== null) {
239
- span.copyOf = entries.get(fields.id);
240
- span.copyOf.copies.push(span);
241
- }
128
+ } else if (fields !== null) {
129
+ span.copyOf = entries.get(fields.id);
130
+ span.copyOf.copies.push(span);
242
131
  }
243
132
  }
244
133
  function embed(value) {
245
- const name = regionNameOf(value);
134
+ let name = regionNameOf(value);
246
135
  stray = null;
247
- if (name !== null && entry !== null && !entry.regions.some((region2) => region2.name === name)) {
248
- const region2 = { name, entry, segs: [] };
249
- entry.regions.push(region2);
250
- order.push(region2);
251
- open = opened(region2);
252
- return;
136
+ const missing = (one) => !entry.regions.some((region2) => region2.name === one);
137
+ if (name !== null && entry !== null) {
138
+ const needed = required(markers.get(entry).type);
139
+ if (needed.length > 0 && !needed.includes(name)) name = needed.find(missing) ?? null;
140
+ if (name !== null && missing(name)) {
141
+ const region2 = { name, entry, segs: [] };
142
+ entry.regions.push(region2);
143
+ order.push(region2);
144
+ open = opened(region2);
145
+ return;
146
+ }
253
147
  }
254
- clean = false;
255
148
  if (open !== null) open = opened(open.region);
256
149
  }
257
150
  return {
@@ -263,7 +156,7 @@ function reader(required) {
263
156
  span.length += length;
264
157
  return;
265
158
  }
266
- if (insert instanceof Y2.Map) marker(insert);
159
+ if (insert instanceof Y.Map) marker(insert);
267
160
  else embed(insert);
268
161
  span.length += 1;
269
162
  },
@@ -291,16 +184,32 @@ function reader(required) {
291
184
  const regions = kept.regions.map(({ name, segs }) => [name, inline(segs)]);
292
185
  return { id: kept.id, type, indent, attrs: attrs?.toJSON() ?? {}, regions: Object.fromEntries(regions) };
293
186
  });
294
- const layout = createLayout(spans, entries, clean, { read, leading: new Set(leading), unread });
187
+ const layout = createLayout(spans, entries, { read, leading: new Set(leading), unread });
295
188
  return { doc: createDoc(blocks), layout };
296
189
  }
297
190
  };
298
191
  }
299
192
  function readShared(text2, required = noRequiredRegions) {
300
193
  const read = reader(required);
301
- for (const op of text2.toDelta()) read.read(op);
194
+ readItems(text2, () => read, read);
302
195
  return read.finish();
303
196
  }
197
+ function readItems(text2, readerOf, read) {
198
+ const attributes = /* @__PURE__ */ new Map();
199
+ for (let item = text2._start; item !== null; item = item.right) {
200
+ const { content } = item;
201
+ if (item.deleted) continue;
202
+ if (content instanceof Y.ContentFormat) {
203
+ if (content.value === null) attributes.delete(content.key);
204
+ else attributes.set(content.key, content.value);
205
+ continue;
206
+ }
207
+ for (const insert of content instanceof Y.ContentString ? [content.str] : content.getContent()) {
208
+ if (insert instanceof Y.Map) read = readerOf(insert);
209
+ read?.read({ insert, attributes: Object.fromEntries(attributes) });
210
+ }
211
+ }
212
+ }
304
213
 
305
214
  // src/yjs/shared.ts
306
215
  function reread(shared) {
@@ -332,9 +241,6 @@ function openRegion(shared, { name, entry }, inline) {
332
241
  reread(shared);
333
242
  }
334
243
 
335
- // src/yjs/sync-block.ts
336
- import * as Y3 from "yjs";
337
-
338
244
  // src/yjs/inline-span.ts
339
245
  var units = (inline) => inline.flatMap(
340
246
  (node) => node.kind === "text" ? Array.from({ length: node.text.length }, (_, i) => text(node.text[i], node.marks)) : [node]
@@ -360,12 +266,12 @@ function isPlain({ span, regions }) {
360
266
  }
361
267
  return span.length === end;
362
268
  }
363
- function rewritten(entry, block, map = entry.map) {
364
- const next = cleanEntry(block, map);
269
+ function adopted(entry, next) {
365
270
  next.copies.push(...entry.copies);
366
271
  for (const copy of next.copies) copy.copyOf = next;
367
272
  return next;
368
273
  }
274
+ var rewritten = (entry, block, map = entry.map) => adopted(entry, cleanEntry(block, map));
369
275
  function crossesStray(layout, index) {
370
276
  const { read, leading, unread } = layout.strays;
371
277
  return unread || read.some((seg) => {
@@ -428,11 +334,8 @@ function removeBlock(shared, id) {
428
334
 
429
335
  // src/yjs/sync-block.ts
430
336
  function syncAttrs(map, before, after) {
431
- const current = map.get("attrs");
432
- if (!(current instanceof Y3.Map)) {
433
- map.set("attrs", new Y3.Map(definedEntries(after)));
434
- return;
435
- }
337
+ const current = attrsMap(map, after);
338
+ if (current === null) return;
436
339
  const kept = new Map(definedEntries(after));
437
340
  for (const key of [...current.keys()]) if (!kept.has(key)) current.delete(key);
438
341
  for (const [key, value] of kept) if (!sameValue(before[key], value)) current.set(key, value);
@@ -451,8 +354,8 @@ function keptNames(before, after) {
451
354
  function syncRegions(shared, entry, before, after) {
452
355
  const { text: text2, layout } = shared;
453
356
  const names = Object.keys(after.regions);
454
- const kept = keptNames(Object.keys(before.regions), names);
455
- const queue = Object.entries(before.regions);
357
+ const queue = entry.regions.map(({ name }) => [name, before.regions[name]]);
358
+ const kept = keptNames(queue.map(([name]) => name), names);
456
359
  let at = spanStart(layout, entry.span) + 1;
457
360
  const dropGone = () => {
458
361
  while (queue.length > 0 && !kept.has(queue[0][0])) deleteText(text2, at, 1 + inlineLength(queue.shift()[1]));
@@ -482,8 +385,7 @@ function syncBlock(shared, before, after, next) {
482
385
  insertBlocks(shared, next, [after]);
483
386
  return;
484
387
  }
485
- if (before.type !== after.type) entry.map.set("type", after.type);
486
- if (before.indent !== after.indent) entry.map.set("indent", after.indent);
388
+ for (const key of ["type", "indent"]) if (before[key] !== after[key]) entry.map.set(key, after[key]);
487
389
  syncAttrs(entry.map, before.attrs, after.attrs);
488
390
  if (plain) {
489
391
  const gains = Object.keys(before.regions).length === 0 && Object.keys(after.regions).length > 0;
@@ -593,8 +495,8 @@ function setAttrs({ shared, after, params }) {
593
495
  const id = params.block;
594
496
  const { map } = shared.layout.entries.get(id);
595
497
  const next = blockById(after, id).attrs;
596
- const attrs = map.get("attrs");
597
- if (!(attrs instanceof Y4.Map)) return void map.set("attrs", new Y4.Map(definedEntries(next)));
498
+ const attrs = attrsMap(map, next);
499
+ if (attrs === null) return;
598
500
  for (const key of Object.keys(params.patch)) {
599
501
  if (next[key] === void 0) attrs.delete(key);
600
502
  else attrs.set(key, next[key]);
@@ -643,94 +545,75 @@ function writeLocalSteps(shared, steps, docs) {
643
545
  });
644
546
  }
645
547
 
646
- // src/yjs/own-change.ts
647
- function ownChange(editor, steps, hint) {
648
- const tr = editor.createTransaction().setOrigin("history").setMeta("addToHistory", false);
649
- for (const step of steps) tr.step(step);
650
- if (hint && sameSelection(validateSelection(tr.doc, editor.schema, hint), hint)) tr.setSelection(hint);
651
- return tr;
652
- }
653
-
654
548
  // src/yjs/seed.ts
655
549
  function seedOrLoad(editor, text2, { origin, seed, required }) {
656
550
  const { blocks } = editor.state.doc;
657
551
  if (text2.length === 0 && seed === "if-empty") {
658
552
  let maps = [];
659
553
  text2.doc.transact(() => maps = writeBlocks(text2, 0, blocks), origin);
660
- const entries = blocks.map((block, i) => cleanEntry(block, maps[i]));
661
- const spans = [emptySpan(), ...entries.map((entry) => entry.span)];
662
- return createLayout(spans, new Map(entries.map((entry) => [entry.id, entry])), true);
554
+ const layout2 = createLayout([emptySpan()], /* @__PURE__ */ new Map());
555
+ placeEntries(layout2, 1, 0, blocks.map((block, i) => cleanEntry(block, maps[i])));
556
+ return layout2;
663
557
  }
664
558
  const { doc, layout } = readShared(text2, required);
665
559
  if (!sameDoc(doc, editor.state.doc)) applyRemote(editor, [replaceDocStep(doc)]);
666
560
  return layout;
667
561
  }
668
562
 
669
- // src/yjs/undo-history.ts
670
- import * as Y5 from "yjs";
671
- var GROUP_DELAY = 500;
672
- var SELECTION = "selection";
673
- function groupOf(tr) {
674
- if (tr.getMeta("closeHistory") === true) return null;
675
- const named = tr.getMeta(HISTORY_GROUP);
676
- if (named !== void 0) return named;
677
- const before = tr.before.selection;
678
- if (tr.origin !== "input" || before?.kind !== "text") return null;
679
- return JSON.stringify([before.head.block, before.head.region]);
680
- }
681
- function undoHistory(text2, origin) {
682
- const manager = new Y5.UndoManager(text2, { trackedOrigins: /* @__PURE__ */ new Set([origin]), captureTimeout: Infinity });
683
- let group = null;
684
- let time = 0;
685
- let before = null;
686
- let hint = null;
687
- manager.on("stack-item-added", ({ stackItem }) => stackItem.meta.set(SELECTION, before));
688
- return {
689
- manager,
690
- record(tr) {
691
- if (!tr.docChanged) {
692
- if (tr.getMeta("closeHistory") === true) group = null;
693
- return;
694
- }
695
- const next = groupOf(tr);
696
- if (next === null || next !== group || tr.time - time >= GROUP_DELAY) manager.stopCapturing();
697
- group = next;
698
- time = tr.time;
699
- before = tr.before.selection;
700
- },
701
- travel(direction, editor) {
702
- const stack = direction === "undo" ? manager.undoStack : manager.redoStack;
703
- const item = stack.at(-1);
704
- if (item === void 0) return false;
705
- hint = item.meta.get(SELECTION) ?? null;
706
- before = editor.state.selection;
707
- group = null;
708
- try {
709
- return (direction === "undo" ? manager.undo() : manager.redo()) !== null;
710
- } finally {
711
- hint = null;
712
- }
713
- },
714
- hint: () => hint,
715
- destroy: () => manager.destroy()
716
- };
563
+ // src/yjs/read-blocks.ts
564
+ import * as Y2 from "yjs";
565
+ function touchedEntries(layout, delta) {
566
+ const touched = /* @__PURE__ */ new Map();
567
+ let at = 0;
568
+ for (const op of delta) {
569
+ const length = op.retain ?? op.delete ?? 0;
570
+ if (op.insert instanceof Y2.Map || op.retain && op.attributes) return null;
571
+ if (op.retain === void 0) {
572
+ const span = spanAt(layout, at, op.insert === void 0);
573
+ const start = spanStart(layout, span);
574
+ if (span.entry === null || start === at || at + length > start + span.length) return null;
575
+ touched.set(span.entry.map, span.entry);
576
+ }
577
+ at += length;
578
+ }
579
+ return touched;
580
+ }
581
+ function readBlocks(shared, entries, doc) {
582
+ const { layout } = shared;
583
+ const readers = /* @__PURE__ */ new Map();
584
+ for (const [map, entry] of entries) {
585
+ if (!isPlain(entry)) return null;
586
+ readers.set(map, reader(shared.required));
587
+ }
588
+ readItems(shared.text, (marker) => readers.get(marker));
589
+ const steps = [];
590
+ for (const [map, entry] of entries) {
591
+ const { doc: one, layout: own } = readers.get(map).finish();
592
+ const next = own.spans[1].entry;
593
+ const at = indexOf(layout, entry.span);
594
+ if (crossesStray(own, 1) || crossesStray(layout, at)) return null;
595
+ placeEntries(layout, at, 1, [adopted(entry, next)]);
596
+ if (!sameValue(blockById(doc, entry.id), one.blocks[0])) steps.push(replaceBlockStep(one.blocks[0]));
597
+ }
598
+ return steps;
717
599
  }
718
600
 
719
601
  // src/yjs/read-split-join.ts
720
- import * as Y6 from "yjs";
602
+ import * as Y3 from "yjs";
721
603
  var bare = (op) => op === void 0 || op.attributes === void 0;
722
604
  function split(layout, delta, required) {
723
605
  const [at, ops] = delta[0]?.retain === void 0 ? [0, delta] : [delta[0].retain, delta.slice(1)];
724
606
  const map = ops[0]?.insert;
725
607
  const name = regionNameOf(ops[1]?.insert);
726
- if (ops.length !== 2 || !(map instanceof Y6.Map) || name === null || !bare(delta[0])) return null;
608
+ if (ops.length !== 2 || !(map instanceof Y3.Map) || name === null || !bare(delta[0])) return null;
727
609
  const marker = readMarker(map);
728
610
  const span = spanAt(layout, at);
729
611
  if (span.entry === null || !isPlain(span.entry)) return null;
730
612
  const region2 = span.entry.regions.at(-1);
731
613
  const seg = region2?.segs[0];
732
614
  const rel = at - spanStart(layout, span);
733
- if (marker === null || seg === void 0 || rel < seg.at || rel > seg.at + seg.length) return null;
615
+ if (marker === null || layout.entries.has(marker.id) || seg === void 0) return null;
616
+ if (rel < seg.at || rel > seg.at + seg.length) return null;
734
617
  if (required(marker.type).some((needed) => needed !== name)) return null;
735
618
  const { id, type, indent, attrs } = marker;
736
619
  const created = { id, type, indent, attrs: attrs?.toJSON() ?? {}, region: name, regions: {} };
@@ -760,101 +643,55 @@ function splitOrJoin(layout, delta, doc, required) {
760
643
  return step;
761
644
  }
762
645
 
763
- // src/yjs/text-steps.ts
764
- function segAt(layout, at, item) {
765
- const span = spanAt(layout, at, item);
766
- const rel = at - spanStart(layout, span);
767
- const seg = span.segs.find((candidate) => candidate.at <= rel && rel <= candidate.at + candidate.length);
768
- return seg === void 0 ? null : { seg, rel };
769
- }
770
- function formatSteps(layout, at, length, attributes) {
771
- const steps = [];
772
- for (let span = spanAt(layout, at, true); ; span = layout.spans[span.index + 1]) {
773
- const start = spanStart(layout, span);
774
- if (start >= at + length) break;
775
- for (const seg of span.segs) {
776
- const from = Math.max(at - start, seg.at);
777
- const to = Math.min(at + length - start, seg.at + seg.length);
778
- if (to <= from) continue;
779
- const { entry, name } = seg.region;
780
- const [first, last] = [offsetIn(seg, from), offsetIn(seg, to)];
781
- for (const [key, value] of Object.entries(attributes)) {
782
- const mark = markFromAttribute(key, value ?? true);
783
- steps.push((value === null ? removeMarkStep : addMarkStep)(entry.id, name, first, last, mark));
784
- }
785
- }
786
- if (span.index + 1 >= layout.spans.length) break;
787
- }
788
- return steps;
789
- }
790
- function textSteps(layout, delta) {
791
- const steps = [];
792
- let at = 0;
793
- for (const op of delta) {
794
- if (op.retain !== void 0) {
795
- if (op.attributes !== void 0) steps.push(...formatSteps(layout, at, op.retain, op.attributes));
796
- at += op.retain;
797
- } else if (op.delete !== void 0) {
798
- const found = segAt(layout, at, true);
799
- if (found === null || found.rel + op.delete > found.seg.at + found.seg.length) return null;
800
- const from = offsetIn(found.seg, found.rel);
801
- const { entry, name } = found.seg.region;
802
- steps.push(replaceInlineStep(entry.id, name, from, from + op.delete, []));
803
- grow(layout, found.seg, found.rel, -op.delete);
804
- } else {
805
- const found = typeof op.insert === "string" || isAtomEmbed(op.insert) ? segAt(layout, at, false) : null;
806
- if (found === null) return null;
807
- const inline = inlineOfOps([op]);
808
- const from = offsetIn(found.seg, found.rel);
809
- const { entry, name } = found.seg.region;
810
- steps.push(replaceInlineStep(entry.id, name, from, from, inline));
811
- grow(layout, found.seg, found.rel, inlineLength(inline));
812
- at += inlineLength(inline);
813
- }
814
- }
815
- return steps;
816
- }
817
-
818
646
  // src/yjs/yjs-to-steps.ts
819
647
  var REREAD = new Error("reread");
820
- function markerSteps(shared, event, doc) {
648
+ function markerSteps(shared, event, doc, read) {
821
649
  const target = event.target;
822
650
  const marker = target.parent === shared.text ? target : target.parent;
651
+ const keys = [...event.keysChanged];
652
+ if (target === marker && keys.includes("id")) throw REREAD;
823
653
  const fields = readMarker(marker);
824
654
  const block = fields === null ? void 0 : blockById(doc, fields.id);
825
- if (block === void 0 || shared.layout.entries.get(block.id)?.map !== marker) return [];
826
- const keys = [...event.keysChanged];
655
+ const entry = block === void 0 ? void 0 : shared.layout.entries.get(block.id);
656
+ if (block === void 0 || entry?.map !== marker || read.has(marker)) return [];
827
657
  if (target !== marker) {
828
658
  if (fields.attrs !== target) return [];
829
659
  return [setAttrsStep(block.id, Object.fromEntries(keys.map((key) => [key, target.get(key)])))];
830
660
  }
831
- if (keys.includes("id")) throw REREAD;
832
- if (keys.every((key) => key === "indent")) return [setIndentStep(block.id, fields.indent)];
833
- const { type, indent, attrs } = fields;
834
- const empty = shared.layout.entries.get(block.id).regions.some((region2) => region2.segs.length === 0);
835
- if (empty || shared.required(type).some((name) => !Object.hasOwn(block.regions, name))) throw REREAD;
836
- return [replaceBlockStep({ ...block, type, indent, attrs: attrs?.toJSON() ?? {} })];
661
+ if (keys.includes("type")) {
662
+ read.set(marker, entry);
663
+ return [];
664
+ }
665
+ const { indent, attrs } = fields;
666
+ if (keys.every((key) => key === "indent")) return [setIndentStep(block.id, indent)];
667
+ return [replaceBlockStep({ ...block, indent, attrs: attrs?.toJSON() ?? {} })];
837
668
  }
838
669
  function contentSteps(shared, events, doc) {
839
670
  const textEvent = events.find((event) => event.target === shared.text);
840
671
  const delta = textEvent?.delta ?? [];
672
+ const touched = touchedEntries(shared.layout, delta);
841
673
  const structure = splitOrJoin(shared.layout, delta, doc, shared.required);
842
674
  const steps = structure === null ? textSteps(shared.layout, delta) : [structure];
843
- if (steps === null) throw REREAD;
844
- let current = steps.reduce((changed, step) => step.apply(changed).doc, doc);
845
- for (const event of events) {
846
- if (event === textEvent) continue;
847
- for (const step of markerSteps(shared, event, current)) {
675
+ if (steps === null && touched === null) throw REREAD;
676
+ const read = steps === null ? touched : /* @__PURE__ */ new Map();
677
+ const all = [];
678
+ let current = doc;
679
+ const take = (more) => {
680
+ if (more === null) throw REREAD;
681
+ for (const step of more) {
848
682
  current = step.apply(current).doc;
849
- steps.push(step);
683
+ all.push(step);
850
684
  }
851
- }
852
- return steps;
685
+ };
686
+ take(steps ?? []);
687
+ for (const event of events) if (event !== textEvent) take(markerSteps(shared, event, current, read));
688
+ if (read.size > 0) take(readBlocks(shared, read, current));
689
+ return { steps: all, structural: read.size > 0 };
853
690
  }
854
691
  function readRemote(shared, events, doc) {
855
692
  try {
856
- return { steps: contentSteps(shared, events, doc), structural: false };
857
- } catch {
693
+ return contentSteps(shared, events, doc);
694
+ } catch (error) {
858
695
  const read = readShared(shared.text, shared.required);
859
696
  shared.layout = read.layout;
860
697
  const blocks = read.doc.blocks.map((block) => {
@@ -862,44 +699,45 @@ function readRemote(shared, events, doc) {
862
699
  return held2 !== void 0 && sameValue(held2, block) ? held2 : block;
863
700
  });
864
701
  const next = createDoc(blocks);
865
- return { steps: sameDoc(next, doc) ? [] : [replaceDocStep(next)], structural: true };
702
+ const failed = error === REREAD ? void 0 : error;
703
+ return { steps: sameDoc(next, doc) ? [] : [replaceDocStep(next)], structural: true, failed };
866
704
  }
867
705
  }
868
706
 
869
707
  // src/yjs/binding.ts
870
- function bind(editor, text2, { origins, seed }) {
708
+ function bind(editor, text2, options) {
709
+ const { origins, seed, onError } = options;
871
710
  const doc = text2.doc;
872
711
  const required = requiredRegions(editor.state.schema);
873
712
  const layout = seedOrLoad(editor, text2, { origin: origins.local, seed, required });
713
+ const history = options.history();
874
714
  const shared = { text: text2, layout, stale: false, required };
875
- const history = undoHistory(text2, origins.local);
876
715
  const ours = (origin) => origin === origins.local || origin === origins.untracked;
877
- let held2 = null;
716
+ const held2 = /* @__PURE__ */ new WeakMap();
878
717
  const written = /* @__PURE__ */ new WeakSet();
879
718
  const hold = (transaction) => {
880
- if (!ours(transaction.origin)) held2 = holdSelection(text2, shared.layout, editor.state.selection);
719
+ if (!ours(transaction.origin)) held2.set(transaction, holdSelection(text2, shared.layout, editor.state.selection));
881
720
  };
882
721
  const observer = (events, transaction) => {
883
722
  if (ours(transaction.origin)) return;
884
- const { steps, structural } = readRemote(shared, events, editor.state.doc);
885
- if (steps.length === 0) return;
886
- if (transaction.origin !== history.manager)
887
- return applyRemote(editor, steps, structural ? restoreSelection(text2, shared.layout, held2) : null);
888
- const tr = ownChange(editor, steps, history.hint());
889
- written.add(tr);
890
- editor.dispatch(tr);
723
+ const { steps, structural, failed } = readRemote(shared, events, editor.state.doc);
724
+ if (steps.length > 0 && transaction.origin !== history.manager) {
725
+ applyRemote(editor, steps, structural ? restoreSelection(text2, shared.layout, held2.get(transaction)) : null);
726
+ } else if (steps.length > 0) {
727
+ const tr = sharedChange(editor, steps, history.hint(), "history");
728
+ written.add(tr);
729
+ editor.dispatch(tr);
730
+ }
731
+ if (failed) onError(failed);
891
732
  };
892
733
  const settle = () => {
893
734
  shared.stale = false;
894
- const read = readShared(text2, required);
895
- shared.layout = read.layout;
896
- if (!sameDoc(read.doc, editor.state.doc)) applyRemote(editor, [replaceDocStep(read.doc)]);
735
+ shared.layout = seedOrLoad(editor, text2, { origin: origins.local, seed: false, required });
897
736
  };
898
737
  doc.on("beforeTransaction", hold);
899
738
  text2.observeDeep(observer);
900
739
  return {
901
740
  editor,
902
- history,
903
741
  shared,
904
742
  local(tr) {
905
743
  if (written.has(tr)) return;
@@ -914,18 +752,59 @@ function bind(editor, text2, { origins, seed }) {
914
752
  stop() {
915
753
  doc.off("beforeTransaction", hold);
916
754
  text2.unobserveDeep(observer);
917
- history.destroy();
918
755
  }
919
756
  };
920
757
  }
921
758
 
759
+ // src/yjs/undo-history.ts
760
+ import * as Y4 from "yjs";
761
+ var GROUP_DELAY = 500;
762
+ var SELECTION = "selection";
763
+ function undoHistory(text2, origin) {
764
+ const manager = new Y4.UndoManager(text2, { trackedOrigins: /* @__PURE__ */ new Set([origin]), captureTimeout: Infinity });
765
+ let group = null;
766
+ let time = 0;
767
+ let before = null;
768
+ let hint = null;
769
+ manager.on("stack-item-added", ({ stackItem }) => stackItem.meta.set(SELECTION, before));
770
+ return {
771
+ manager,
772
+ record(tr) {
773
+ if (!tr.docChanged) {
774
+ if (tr.getMeta("closeHistory") === true) group = null;
775
+ return;
776
+ }
777
+ const next = groupOf(tr);
778
+ if (next === null || next !== group || tr.time - time >= GROUP_DELAY) manager.stopCapturing();
779
+ group = next;
780
+ time = tr.time;
781
+ before = tr.before.selection;
782
+ },
783
+ travel(direction, editor) {
784
+ const item = manager[`${direction}Stack`].at(-1);
785
+ if (item === void 0) return false;
786
+ hint = item.meta.get(SELECTION) ?? null;
787
+ before = editor.state.selection;
788
+ group = null;
789
+ try {
790
+ return manager[direction]() !== null;
791
+ } finally {
792
+ hint = null;
793
+ }
794
+ },
795
+ hint: () => hint
796
+ };
797
+ }
798
+
922
799
  // src/yjs/index.ts
923
800
  function yjsCollaboration(options) {
924
801
  const { doc, field = "quoin", awareness, user, seed = "if-empty" } = options;
925
802
  const onError = options.onError ?? ((error) => console.error(error));
926
803
  const text2 = doc.getText(field);
927
804
  const origins = { local: { user }, untracked: {} };
805
+ let history;
928
806
  let binding = null;
807
+ let disconnects = 0;
929
808
  const collaboration = {
930
809
  doc,
931
810
  text: text2,
@@ -937,11 +816,22 @@ function yjsCollaboration(options) {
937
816
  onError(new Error("A Yjs collaboration connects one editor at a time; this editor stays unconnected."));
938
817
  return () => void 0;
939
818
  }
940
- const current = bind(editor, text2, { origins, seed });
819
+ const current = bind(editor, text2, {
820
+ origins,
821
+ seed,
822
+ onError,
823
+ history: () => history ??= undoHistory(text2, origins.local)
824
+ });
941
825
  binding = current;
942
826
  return () => {
943
827
  current.stop();
944
828
  if (binding === current) binding = null;
829
+ const at = ++disconnects;
830
+ setTimeout(() => {
831
+ if (binding !== null || at !== disconnects) return;
832
+ history?.manager.destroy();
833
+ history = void 0;
834
+ }, 16);
945
835
  };
946
836
  },
947
837
  onLocalTransaction: (tr, state) => {
@@ -950,8 +840,8 @@ function yjsCollaboration(options) {
950
840
  history: {
951
841
  undo: () => binding?.travel("undo") ?? false,
952
842
  redo: () => binding?.travel("redo") ?? false,
953
- canUndo: () => binding?.history.manager.canUndo() ?? false,
954
- canRedo: () => binding?.history.manager.canRedo() ?? false
843
+ canUndo: () => binding !== null && history.manager.canUndo(),
844
+ canRedo: () => binding !== null && history.manager.canRedo()
955
845
  }
956
846
  };
957
847
  holdBinding(collaboration, () => binding);