@dou-ui/sheet 0.0.0-stage → 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -2
  3. package/dist/cell-types.js +20 -0
  4. package/dist/cell-types.js.map +1 -0
  5. package/dist/code/code-formula-bar.js +6 -0
  6. package/dist/code/code-formula-bar.js.map +1 -0
  7. package/dist/code/code-formula-bar.vue_vue_type_script_setup_true_lang.js +192 -0
  8. package/dist/code/code-formula-bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  9. package/dist/code/index.js +12 -0
  10. package/dist/code/index.js.map +1 -0
  11. package/dist/code/language.js +51 -0
  12. package/dist/code/language.js.map +1 -0
  13. package/dist/code/style.d.ts +1 -0
  14. package/dist/code/style.js +2 -0
  15. package/dist/collaboration/anchor.js +143 -0
  16. package/dist/collaboration/anchor.js.map +1 -0
  17. package/dist/collaboration/index.js +770 -0
  18. package/dist/collaboration/index.js.map +1 -0
  19. package/dist/collaboration/peers.js +87 -0
  20. package/dist/collaboration/peers.js.map +1 -0
  21. package/dist/collaboration/shared.js +450 -0
  22. package/dist/collaboration/shared.js.map +1 -0
  23. package/dist/components/cell-panel.js +6 -0
  24. package/dist/components/cell-panel.js.map +1 -0
  25. package/dist/components/cell-panel.vue_vue_type_script_setup_true_lang.js +70 -0
  26. package/dist/components/cell-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  27. package/dist/components/cell-renders.js +40 -0
  28. package/dist/components/cell-renders.js.map +1 -0
  29. package/dist/components/date-panel.js +6 -0
  30. package/dist/components/date-panel.js.map +1 -0
  31. package/dist/components/date-panel.vue_vue_type_script_setup_true_lang.js +48 -0
  32. package/dist/components/date-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  33. package/dist/components/filter-panel.js +6 -0
  34. package/dist/components/filter-panel.js.map +1 -0
  35. package/dist/components/filter-panel.vue_vue_type_script_setup_true_lang.js +259 -0
  36. package/dist/components/filter-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  37. package/dist/components/format-dialog.js +6 -0
  38. package/dist/components/format-dialog.js.map +1 -0
  39. package/dist/components/format-dialog.vue_vue_type_script_setup_true_lang.js +432 -0
  40. package/dist/components/format-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  41. package/dist/components/format-list.js +6 -0
  42. package/dist/components/format-list.js.map +1 -0
  43. package/dist/components/format-list.vue_vue_type_script_setup_true_lang.js +187 -0
  44. package/dist/components/format-list.vue_vue_type_script_setup_true_lang.js.map +1 -0
  45. package/dist/components/format-presets.js +97 -0
  46. package/dist/components/format-presets.js.map +1 -0
  47. package/dist/components/option-panel.js +6 -0
  48. package/dist/components/option-panel.js.map +1 -0
  49. package/dist/components/option-panel.vue_vue_type_script_setup_true_lang.js +117 -0
  50. package/dist/components/option-panel.vue_vue_type_script_setup_true_lang.js.map +1 -0
  51. package/dist/components/sheet-comment.js +6 -0
  52. package/dist/components/sheet-comment.js.map +1 -0
  53. package/dist/components/sheet-comment.vue_vue_type_script_setup_true_lang.js +104 -0
  54. package/dist/components/sheet-comment.vue_vue_type_script_setup_true_lang.js.map +1 -0
  55. package/dist/components/sheet-formula-bar.js +6 -0
  56. package/dist/components/sheet-formula-bar.js.map +1 -0
  57. package/dist/components/sheet-formula-bar.vue_vue_type_script_setup_true_lang.js +124 -0
  58. package/dist/components/sheet-formula-bar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  59. package/dist/components/sheet-link.js +6 -0
  60. package/dist/components/sheet-link.js.map +1 -0
  61. package/dist/components/sheet-link.vue_vue_type_script_setup_true_lang.js +249 -0
  62. package/dist/components/sheet-link.vue_vue_type_script_setup_true_lang.js.map +1 -0
  63. package/dist/components/sheet-menu.js +6 -0
  64. package/dist/components/sheet-menu.js.map +1 -0
  65. package/dist/components/sheet-menu.vue_vue_type_script_setup_true_lang.js +115 -0
  66. package/dist/components/sheet-menu.vue_vue_type_script_setup_true_lang.js.map +1 -0
  67. package/dist/components/sheet-name-box.js +6 -0
  68. package/dist/components/sheet-name-box.js.map +1 -0
  69. package/dist/components/sheet-name-box.vue_vue_type_script_setup_true_lang.js +91 -0
  70. package/dist/components/sheet-name-box.vue_vue_type_script_setup_true_lang.js.map +1 -0
  71. package/dist/components/sheet-note.js +6 -0
  72. package/dist/components/sheet-note.js.map +1 -0
  73. package/dist/components/sheet-note.vue_vue_type_script_setup_true_lang.js +146 -0
  74. package/dist/components/sheet-note.vue_vue_type_script_setup_true_lang.js.map +1 -0
  75. package/dist/components/sheet-outline.js +6 -0
  76. package/dist/components/sheet-outline.js.map +1 -0
  77. package/dist/components/sheet-outline.vue_vue_type_script_setup_true_lang.js +237 -0
  78. package/dist/components/sheet-outline.vue_vue_type_script_setup_true_lang.js.map +1 -0
  79. package/dist/components/sheet-tabs.js +6 -0
  80. package/dist/components/sheet-tabs.js.map +1 -0
  81. package/dist/components/sheet-tabs.vue_vue_type_script_setup_true_lang.js +487 -0
  82. package/dist/components/sheet-tabs.vue_vue_type_script_setup_true_lang.js.map +1 -0
  83. package/dist/components/sheet-toolbar.js +6 -0
  84. package/dist/components/sheet-toolbar.js.map +1 -0
  85. package/dist/components/sheet-toolbar.vue_vue_type_script_setup_true_lang.js +1562 -0
  86. package/dist/components/sheet-toolbar.vue_vue_type_script_setup_true_lang.js.map +1 -0
  87. package/dist/components/validation-dialog.js +6 -0
  88. package/dist/components/validation-dialog.js.map +1 -0
  89. package/dist/components/validation-dialog.vue_vue_type_script_setup_true_lang.js +370 -0
  90. package/dist/components/validation-dialog.vue_vue_type_script_setup_true_lang.js.map +1 -0
  91. package/dist/context.js +12 -0
  92. package/dist/context.js.map +1 -0
  93. package/dist/core/address.js +256 -0
  94. package/dist/core/address.js.map +1 -0
  95. package/dist/core/axis.js +72 -0
  96. package/dist/core/axis.js.map +1 -0
  97. package/dist/core/cell-type.js +30 -0
  98. package/dist/core/cell-type.js.map +1 -0
  99. package/dist/core/clipboard.js +141 -0
  100. package/dist/core/clipboard.js.map +1 -0
  101. package/dist/core/commands.js +63 -0
  102. package/dist/core/commands.js.map +1 -0
  103. package/dist/core/comments.js +74 -0
  104. package/dist/core/comments.js.map +1 -0
  105. package/dist/core/conditional.js +362 -0
  106. package/dist/core/conditional.js.map +1 -0
  107. package/dist/core/csv.js +191 -0
  108. package/dist/core/csv.js.map +1 -0
  109. package/dist/core/data.js +118 -0
  110. package/dist/core/data.js.map +1 -0
  111. package/dist/core/document.js +187 -0
  112. package/dist/core/document.js.map +1 -0
  113. package/dist/core/extension.js +60 -0
  114. package/dist/core/extension.js.map +1 -0
  115. package/dist/core/file.js +336 -0
  116. package/dist/core/file.js.map +1 -0
  117. package/dist/core/fill.js +153 -0
  118. package/dist/core/fill.js.map +1 -0
  119. package/dist/core/find.js +42 -0
  120. package/dist/core/find.js.map +1 -0
  121. package/dist/core/format.js +404 -0
  122. package/dist/core/format.js.map +1 -0
  123. package/dist/core/group.js +134 -0
  124. package/dist/core/group.js.map +1 -0
  125. package/dist/core/history.js +68 -0
  126. package/dist/core/history.js.map +1 -0
  127. package/dist/core/index.js +17 -0
  128. package/dist/core/link.js +34 -0
  129. package/dist/core/link.js.map +1 -0
  130. package/dist/core/merge.js +105 -0
  131. package/dist/core/merge.js.map +1 -0
  132. package/dist/core/model.js +48 -0
  133. package/dist/core/model.js.map +1 -0
  134. package/dist/core/nav.js +44 -0
  135. package/dist/core/nav.js.map +1 -0
  136. package/dist/core/paint.js +106 -0
  137. package/dist/core/paint.js.map +1 -0
  138. package/dist/core/plain-cell-types.js +54 -0
  139. package/dist/core/plain-cell-types.js.map +1 -0
  140. package/dist/core/protect.js +246 -0
  141. package/dist/core/protect.js.map +1 -0
  142. package/dist/core/selection.js +37 -0
  143. package/dist/core/selection.js.map +1 -0
  144. package/dist/core/transaction.js +1582 -0
  145. package/dist/core/transaction.js.map +1 -0
  146. package/dist/core/validation.js +135 -0
  147. package/dist/core/validation.js.map +1 -0
  148. package/dist/core/versions.js +161 -0
  149. package/dist/core/versions.js.map +1 -0
  150. package/dist/export/color.js +36 -0
  151. package/dist/export/color.js.map +1 -0
  152. package/dist/export/draw.js +316 -0
  153. package/dist/export/draw.js.map +1 -0
  154. package/dist/export/index.js +390 -0
  155. package/dist/export/index.js.map +1 -0
  156. package/dist/formula/edit.js +210 -0
  157. package/dist/formula/edit.js.map +1 -0
  158. package/dist/formula/engine.js +526 -0
  159. package/dist/formula/engine.js.map +1 -0
  160. package/dist/formula/error.js +39 -0
  161. package/dist/formula/error.js.map +1 -0
  162. package/dist/formula/functions.js +1493 -0
  163. package/dist/formula/functions.js.map +1 -0
  164. package/dist/formula/help.js +408 -0
  165. package/dist/formula/help.js.map +1 -0
  166. package/dist/formula/index.js +7 -0
  167. package/dist/formula/parse.js +369 -0
  168. package/dist/formula/parse.js.map +1 -0
  169. package/dist/formula/values.js +123 -0
  170. package/dist/formula/values.js.map +1 -0
  171. package/dist/formulas.js +30 -0
  172. package/dist/formulas.js.map +1 -0
  173. package/dist/index.js +39 -0
  174. package/dist/index.js.map +1 -0
  175. package/dist/locale.js +1312 -0
  176. package/dist/locale.js.map +1 -0
  177. package/dist/sheet.js +6 -0
  178. package/dist/sheet.js.map +1 -0
  179. package/dist/sheet.vue_vue_type_script_setup_true_lang.js +7166 -0
  180. package/dist/sheet.vue_vue_type_script_setup_true_lang.js.map +1 -0
  181. package/dist/style.css +1 -0
  182. package/dist/style.d.ts +1 -0
  183. package/dist/style.js +17 -0
  184. package/dist/types/cell-types.d.ts +2 -0
  185. package/dist/types/code/code-formula-bar.vue.d.ts +3 -0
  186. package/dist/types/code/index.d.ts +12 -0
  187. package/dist/types/code/language.d.ts +13 -0
  188. package/dist/types/collaboration/anchor.d.ts +65 -0
  189. package/dist/types/collaboration/index.d.ts +59 -0
  190. package/dist/types/collaboration/peers.d.ts +21 -0
  191. package/dist/types/collaboration/shared.d.ts +75 -0
  192. package/dist/types/components/cell-panel.vue.d.ts +20 -0
  193. package/dist/types/components/cell-renders.d.ts +9 -0
  194. package/dist/types/components/date-panel.vue.d.ts +9 -0
  195. package/dist/types/components/filter-panel.vue.d.ts +21 -0
  196. package/dist/types/components/format-dialog.vue.d.ts +24 -0
  197. package/dist/types/components/format-list.vue.d.ts +25 -0
  198. package/dist/types/components/format-presets.d.ts +30 -0
  199. package/dist/types/components/option-panel.vue.d.ts +13 -0
  200. package/dist/types/components/sheet-comment.vue.d.ts +29 -0
  201. package/dist/types/components/sheet-formula-bar.vue.d.ts +3 -0
  202. package/dist/types/components/sheet-link.vue.d.ts +32 -0
  203. package/dist/types/components/sheet-menu.vue.d.ts +20 -0
  204. package/dist/types/components/sheet-name-box.vue.d.ts +3 -0
  205. package/dist/types/components/sheet-note.vue.d.ts +22 -0
  206. package/dist/types/components/sheet-outline.vue.d.ts +36 -0
  207. package/dist/types/components/sheet-tabs.vue.d.ts +9 -0
  208. package/dist/types/components/sheet-toolbar.vue.d.ts +11 -0
  209. package/dist/types/components/validation-dialog.vue.d.ts +25 -0
  210. package/dist/types/context.d.ts +189 -0
  211. package/dist/types/core/address.d.ts +109 -0
  212. package/dist/types/core/axis.d.ts +23 -0
  213. package/dist/types/core/cell-type.d.ts +157 -0
  214. package/dist/types/core/clipboard.d.ts +48 -0
  215. package/dist/types/core/commands.d.ts +76 -0
  216. package/dist/types/core/comments.d.ts +22 -0
  217. package/dist/types/core/conditional.d.ts +114 -0
  218. package/dist/types/core/csv.d.ts +93 -0
  219. package/dist/types/core/data.d.ts +26 -0
  220. package/dist/types/core/document.d.ts +49 -0
  221. package/dist/types/core/extension.d.ts +177 -0
  222. package/dist/types/core/file.d.ts +301 -0
  223. package/dist/types/core/fill.d.ts +23 -0
  224. package/dist/types/core/find.d.ts +39 -0
  225. package/dist/types/core/format.d.ts +47 -0
  226. package/dist/types/core/group.d.ts +76 -0
  227. package/dist/types/core/history.d.ts +27 -0
  228. package/dist/types/core/index.d.ts +33 -0
  229. package/dist/types/core/link.d.ts +14 -0
  230. package/dist/types/core/merge.d.ts +26 -0
  231. package/dist/types/core/model.d.ts +363 -0
  232. package/dist/types/core/nav.d.ts +15 -0
  233. package/dist/types/core/paint.d.ts +19 -0
  234. package/dist/types/core/plain-cell-types.d.ts +6 -0
  235. package/dist/types/core/protect.d.ts +34 -0
  236. package/dist/types/core/selection.d.ts +25 -0
  237. package/dist/types/core/transaction.d.ts +470 -0
  238. package/dist/types/core/validation.d.ts +55 -0
  239. package/dist/types/core/versions.d.ts +38 -0
  240. package/dist/types/export/color.d.ts +7 -0
  241. package/dist/types/export/draw.d.ts +98 -0
  242. package/dist/types/export/index.d.ts +47 -0
  243. package/dist/types/formula/edit.d.ts +62 -0
  244. package/dist/types/formula/engine.d.ts +99 -0
  245. package/dist/types/formula/error.d.ts +30 -0
  246. package/dist/types/formula/functions.d.ts +62 -0
  247. package/dist/types/formula/help.d.ts +12 -0
  248. package/dist/types/formula/index.d.ts +13 -0
  249. package/dist/types/formula/parse.d.ts +92 -0
  250. package/dist/types/formula/values.d.ts +65 -0
  251. package/dist/types/formulas.d.ts +32 -0
  252. package/dist/types/index.d.ts +225 -0
  253. package/dist/types/locale.d.ts +531 -0
  254. package/dist/types/sheet.vue.d.ts +60 -0
  255. package/dist/types/types.d.ts +498 -0
  256. package/dist/types/use-comments.d.ts +47 -0
  257. package/dist/types/use-messages.d.ts +7 -0
  258. package/dist/use-comments.js +130 -0
  259. package/dist/use-comments.js.map +1 -0
  260. package/dist/use-messages.js +29 -0
  261. package/dist/use-messages.js.map +1 -0
  262. package/package.json +93 -4
@@ -0,0 +1,770 @@
1
+ import { boundsOf } from "../core/address.js";
2
+ import { colCountOf, rowCountOf } from "../core/model.js";
3
+ import { defineSheetExtension } from "../core/extension.js";
4
+ import { sheetKey } from "../core/transaction.js";
5
+ import { SheetLayout, anchorCell, hasRefs, lineOf, resolveCell } from "./anchor.js";
6
+ import { createPeers } from "./peers.js";
7
+ import { ANCHORED_META, anchorMeta, cellAt, cellKey, cellOfKey, fillBook, increasingRun, isBookKey, isMetaKey, layoutSheet, makeIds, partsOf, readBook, readLayout, readSheet, resolveMeta, sheetParts, splitThread, syncList, threadKey, withThread, writeSheet } from "./shared.js";
8
+ import { applySharedCommentAction, collaborationColors, readSharedComments } from "dou-ui";
9
+ import { nextTick, shallowRef, watch } from "vue";
10
+ import * as Y from "yjs";
11
+ // src/collaboration/index.ts
12
+ var same = (a, b) => a === b || (a == null || a === "") && (b == null || b === "") || typeof a === "object" && typeof b === "object" && JSON.stringify(a) === JSON.stringify(b);
13
+ var selectionOf = (active, ranges) => ({
14
+ active,
15
+ ranges: ranges.map((b) => ({
16
+ start: {
17
+ row: b.top,
18
+ col: b.left
19
+ },
20
+ end: {
21
+ row: b.bottom,
22
+ col: b.right
23
+ }
24
+ }))
25
+ });
26
+ /** Writes the named styles or types a change touched. */
27
+ function writeNamed(names, map, own) {
28
+ for (const name of names) {
29
+ const value = own?.[name];
30
+ if (value === void 0) map.delete(name);
31
+ else if (!same(map.get(name), value)) map.set(name, value);
32
+ }
33
+ }
34
+ /** Writes the sizes of the lines a change touched, by line id. */
35
+ function writeSizes(keys, map, lines, own) {
36
+ for (const line of keys) {
37
+ const at = lines.indexOf(line);
38
+ if (at < 0) continue;
39
+ const size = own?.[at];
40
+ if (size == null) map.delete(line);
41
+ else if (map.get(line) !== size) map.set(line, size);
42
+ }
43
+ }
44
+ var isEmpty = (cell) => cell == null || cell === "";
45
+ var dirtyNone = () => ({
46
+ all: false,
47
+ sheets: false,
48
+ whole: /* @__PURE__ */ new Set(),
49
+ names: false,
50
+ styles: /* @__PURE__ */ new Set(),
51
+ types: /* @__PURE__ */ new Set(),
52
+ bySheet: /* @__PURE__ */ new Map()
53
+ });
54
+ var isDirty = (d) => d.all || d.sheets || d.whole.size > 0 || d.styles.size > 0 || d.types.size > 0 || d.bySheet.size > 0;
55
+ function sheetDirty(dirty, id) {
56
+ let entry = dirty.bySheet.get(id);
57
+ if (!entry) dirty.bySheet.set(id, entry = {
58
+ lines: {
59
+ row: false,
60
+ col: false
61
+ },
62
+ cells: /* @__PURE__ */ new Set(),
63
+ rowSizes: /* @__PURE__ */ new Set(),
64
+ colSizes: /* @__PURE__ */ new Set(),
65
+ meta: /* @__PURE__ */ new Set()
66
+ });
67
+ return entry;
68
+ }
69
+ /** Notes what a Yjs event changed. Paths are from the `book` map. */
70
+ function collect(dirty, event) {
71
+ const path = event.path;
72
+ const keys = event instanceof Y.YMapEvent ? event.keysChanged : /* @__PURE__ */ new Set();
73
+ if (path.length === 0) return void (dirty.all = true);
74
+ const [top, id, part] = path;
75
+ if (top === "styles") for (const key of keys) dirty.styles.add(key);
76
+ else if (top === "types") for (const key of keys) dirty.types.add(key);
77
+ else if (top === "order") dirty.sheets = true;
78
+ else if (top === "sheets") {
79
+ if (path.length === 1) {
80
+ dirty.sheets = true;
81
+ for (const key of keys) dirty.whole.add(key);
82
+ } else if (path.length === 2) dirty.whole.add(id);
83
+ else {
84
+ const entry = sheetDirty(dirty, id);
85
+ if (part === "rows") entry.lines.row = true;
86
+ else if (part === "cols") entry.lines.col = true;
87
+ else if (part === "cells") for (const key of keys) entry.cells.add(key);
88
+ else if (part === "rowSizes") for (const key of keys) entry.rowSizes.add(key);
89
+ else if (part === "colSizes") for (const key of keys) entry.colSizes.add(key);
90
+ else if (part === "meta") for (const key of keys) {
91
+ entry.meta.add(key);
92
+ if (key === "name") dirty.names = true;
93
+ }
94
+ }
95
+ }
96
+ }
97
+ /**
98
+ * Steps that bring a sheet's lines from `from` to `to`, both lists of ids:
99
+ * removed lines first, then the fewest moves, then the new lines. The
100
+ * cells move with their lines; the new lines are empty.
101
+ */
102
+ function stepLines(tr, sheet, axis, from, to) {
103
+ const ids = from.slice();
104
+ let changed = false;
105
+ const wanted = new Set(to);
106
+ for (let i = ids.length - 1; i >= 0;) {
107
+ if (wanted.has(ids[i])) {
108
+ i--;
109
+ continue;
110
+ }
111
+ let start = i;
112
+ while (start > 0 && !wanted.has(ids[start - 1])) start--;
113
+ tr.step({
114
+ type: "removeLines",
115
+ sheet,
116
+ axis,
117
+ index: start,
118
+ count: i - start + 1
119
+ });
120
+ ids.splice(start, i - start + 1);
121
+ changed = true;
122
+ i = start - 1;
123
+ }
124
+ const present = new Set(ids);
125
+ const target = to.filter((id) => present.has(id));
126
+ const rank = new Map(target.map((id, i) => [id, i]));
127
+ const run = increasingRun(ids.map((id) => rank.get(id)));
128
+ const placed = new Set(ids.filter((_, i) => run.has(i)));
129
+ target.forEach((id, k) => {
130
+ if (placed.has(id)) return;
131
+ const at = ids.indexOf(id);
132
+ ids.splice(at, 1);
133
+ const dest = k === 0 ? 0 : ids.indexOf(target[k - 1]) + 1;
134
+ ids.splice(dest, 0, id);
135
+ placed.add(id);
136
+ tr.step({
137
+ type: "moveLines",
138
+ sheet,
139
+ axis,
140
+ from: at,
141
+ count: 1,
142
+ to: dest >= at ? dest + 1 : dest
143
+ });
144
+ changed = true;
145
+ });
146
+ for (let k = 0; k < to.length;) {
147
+ if (present.has(to[k])) {
148
+ k++;
149
+ continue;
150
+ }
151
+ let end = k;
152
+ while (end < to.length && !present.has(to[end])) end++;
153
+ tr.step({
154
+ type: "insertLines",
155
+ sheet,
156
+ axis,
157
+ index: k,
158
+ count: end - k
159
+ });
160
+ changed = true;
161
+ k = end;
162
+ }
163
+ return changed;
164
+ }
165
+ /**
166
+ * Edit a workbook together through a Yjs document. Every row and column
167
+ * has an id there; cells, sizes, formulas and rules are kept by those ids,
168
+ * so two people inserting, deleting or moving lines at once keep each
169
+ * other's cells in place, and formulas still point at the cells they were
170
+ * written for. The grid's `v-model` only mirrors the shared workbook: a
171
+ * workbook set through `v-model` from outside is not written back. Undo
172
+ * only takes back this user's own changes. With `awareness`, each person
173
+ * sees the others' selections and the cells they edit, in their colors.
174
+ */
175
+ function collaboration(options) {
176
+ const { book, awareness, user } = options;
177
+ const ydoc = book.doc;
178
+ if (!ydoc) throw new Error("[@dou-ui/sheet] the book map must be in a Y.Doc");
179
+ if (awareness && user) {
180
+ const color = user.color ?? collaborationColors[ydoc.clientID % collaborationColors.length];
181
+ awareness.setLocalStateField("user", {
182
+ name: user.name,
183
+ color
184
+ });
185
+ }
186
+ /** This grid's own changes, which undo can take back. */
187
+ const tracked = { sheet: "tracked" };
188
+ /** Changes undo leaves alone, e.g. filling the shared workbook. */
189
+ const untracked = { sheet: "untracked" };
190
+ const undoManager = new Y.UndoManager(book, {
191
+ trackedOrigins: /* @__PURE__ */ new Set([tracked]),
192
+ captureTimeout: 500
193
+ });
194
+ const ids = makeIds(ydoc);
195
+ let context;
196
+ let parts = null;
197
+ /** The sheets and lines the grid shows, by id: the shared workbook as last applied. */
198
+ let layout = new SheetLayout();
199
+ /** Set while shared changes are applied to the grid, so they aren't written back. */
200
+ let applying = false;
201
+ /** What undo or redo is running, to name the change. */
202
+ let travelling = null;
203
+ let restore;
204
+ let lastGroup;
205
+ /** Counts the changes applied from the shared workbook, for what draws by line ids. */
206
+ const revision = shallowRef(0);
207
+ function storeView(sheet, selection) {
208
+ const here = layout.sheets.get(sheet);
209
+ if (!here) return void 0;
210
+ const row = (n) => here.rows.ids[n] ?? n;
211
+ const col = (n) => here.cols.ids[n] ?? n;
212
+ return {
213
+ sheet,
214
+ active: [row(selection.active.row), col(selection.active.col)],
215
+ ranges: selection.ranges.slice(0, 20).map((range) => {
216
+ const b = boundsOf(range);
217
+ return [
218
+ row(b.top),
219
+ col(b.left),
220
+ row(b.bottom),
221
+ col(b.right)
222
+ ];
223
+ })
224
+ };
225
+ }
226
+ function readView(view) {
227
+ const here = layout.sheets.get(view.sheet);
228
+ if (!here) return null;
229
+ const ranges = [];
230
+ for (const [top, left, bottom, right] of view.ranges) {
231
+ const b = {
232
+ top: lineOf(here.rows, top),
233
+ left: lineOf(here.cols, left),
234
+ bottom: lineOf(here.rows, bottom),
235
+ right: lineOf(here.cols, right)
236
+ };
237
+ if (b.top >= 0 && b.left >= 0 && b.bottom >= 0 && b.right >= 0) ranges.push({
238
+ top: Math.min(b.top, b.bottom),
239
+ left: Math.min(b.left, b.right),
240
+ bottom: Math.max(b.top, b.bottom),
241
+ right: Math.max(b.left, b.right)
242
+ });
243
+ }
244
+ const row = lineOf(here.rows, view.active[0]);
245
+ const col = lineOf(here.cols, view.active[1]);
246
+ return {
247
+ active: row >= 0 && col >= 0 ? {
248
+ row,
249
+ col
250
+ } : ranges[0] ? {
251
+ row: ranges[0].top,
252
+ col: ranges[0].left
253
+ } : null,
254
+ ranges
255
+ };
256
+ }
257
+ undoManager.on("stack-item-added", (event) => {
258
+ const id = context?.sheet.value.id;
259
+ const view = id != null && context ? storeView(id, context.selection.value) : void 0;
260
+ if (view) event.stackItem.meta.set("view", view);
261
+ });
262
+ undoManager.on("stack-item-popped", (event) => {
263
+ restore = event.stackItem.meta.get("view");
264
+ });
265
+ /** Writes what a transaction changed into the shared workbook. */
266
+ function writeChanges(tr, shared) {
267
+ const touched = /* @__PURE__ */ new Map();
268
+ const touch = (id) => {
269
+ let entry = touched.get(id);
270
+ if (!entry) touched.set(id, entry = {
271
+ cells: /* @__PURE__ */ new Set(),
272
+ rowSizes: /* @__PURE__ */ new Set(),
273
+ colSizes: /* @__PURE__ */ new Set(),
274
+ meta: /* @__PURE__ */ new Set(),
275
+ lines: {
276
+ row: false,
277
+ col: false
278
+ },
279
+ removed: {
280
+ row: [],
281
+ col: []
282
+ }
283
+ });
284
+ return entry;
285
+ };
286
+ let sheetsChanged = false;
287
+ /** Sheets added in this change, also ones taken out and put back: written whole. */
288
+ const fresh = /* @__PURE__ */ new Set();
289
+ const styles = /* @__PURE__ */ new Set();
290
+ const types = /* @__PURE__ */ new Set();
291
+ /** The workbook's own settings that changed, such as `protect`. */
292
+ const bookKeys = /* @__PURE__ */ new Set();
293
+ for (const step of tr.steps) if (step.type === "setStyle") styles.add(step.name);
294
+ else if (step.type === "setType") types.add(step.name);
295
+ else if (step.type === "insertSheet") {
296
+ sheetsChanged = true;
297
+ if (step.data.id != null) fresh.add(step.data.id);
298
+ } else if (step.type === "removeSheet" || step.type === "moveSheet") sheetsChanged = true;
299
+ else if (step.type === "updateBook") for (const key of Object.keys(step.patch)) bookKeys.add(key);
300
+ else {
301
+ const here = fresh.has(step.sheet) ? void 0 : layout.sheets.get(step.sheet);
302
+ if (!here) continue;
303
+ const t = touch(here.id);
304
+ const lineAt = (axis, index) => {
305
+ const lines = axis === "row" ? here.rows : here.cols;
306
+ if (index >= lines.ids.length) {
307
+ lines.ids.push(...ids.many(index + 1 - lines.ids.length));
308
+ lines.changed();
309
+ t.lines[axis] = true;
310
+ }
311
+ return lines.ids[index];
312
+ };
313
+ if (step.type === "setCell") t.cells.add(cellKey(lineAt("row", step.row), lineAt("col", step.col)));
314
+ else if (step.type === "setSize") (step.axis === "row" ? t.rowSizes : t.colSizes).add(lineAt(step.axis, step.index));
315
+ else if (step.type === "updateSheet") for (const key of Object.keys(step.patch)) t.meta.add(key);
316
+ else {
317
+ const { axis } = step;
318
+ const lines = axis === "row" ? here.rows : here.cols;
319
+ t.lines[axis] = true;
320
+ if (step.type === "insertLines") {
321
+ if (step.index > 0) lineAt(axis, step.index - 1);
322
+ const added = ids.many(step.count);
323
+ lines.ids.splice(step.index, 0, ...added);
324
+ lines.changed();
325
+ step.cells?.forEach((part, r) => part?.forEach((cell, c) => {
326
+ if (isEmpty(cell)) return;
327
+ t.cells.add(axis === "row" ? cellKey(added[r], lineAt("col", c)) : cellKey(lineAt("row", r), added[c]));
328
+ }));
329
+ step.sizes?.forEach((size, i) => {
330
+ if (size != null) (axis === "row" ? t.rowSizes : t.colSizes).add(added[i]);
331
+ });
332
+ } else if (step.type === "removeLines") {
333
+ t.removed[axis].push(...lines.ids.splice(step.index, step.count));
334
+ lines.changed();
335
+ } else {
336
+ lineAt(axis, Math.max(step.from + step.count, step.to) - 1);
337
+ const block = lines.ids.splice(step.from, step.count);
338
+ lines.ids.splice(step.to > step.from ? step.to - step.count : step.to, 0, ...block);
339
+ lines.changed();
340
+ }
341
+ }
342
+ }
343
+ const sheets = tr.doc.sheets;
344
+ const byId = new Map(sheets.map((sheet) => [sheet.id, sheet]));
345
+ if (sheetsChanged || sheets.some((sheet) => !layout.sheets.has(sheet.id))) {
346
+ for (const id of Array.from(layout.sheets.keys())) if (!byId.has(id) || fresh.has(id)) {
347
+ shared.sheets.delete(id);
348
+ layout.sheets.delete(id);
349
+ touched.delete(id);
350
+ }
351
+ const added = [];
352
+ for (const sheet of sheets) if (!layout.sheets.has(sheet.id)) {
353
+ layout.sheets.set(sheet.id, layoutSheet(sheet, sheet.id, ids));
354
+ added.push(sheet);
355
+ }
356
+ for (const sheet of sheets) layout.sheets.get(sheet.id).name = sheet.name;
357
+ for (const sheet of added) writeSheet(shared.sheets, sheet, layout.sheets.get(sheet.id), layout);
358
+ syncList(shared.order, sheets.map((sheet) => sheet.id));
359
+ }
360
+ for (const sheet of sheets) {
361
+ const here = layout.sheets.get(sheet.id);
362
+ if (here) here.name = sheet.name;
363
+ }
364
+ for (const [id, t] of touched) {
365
+ const here = layout.sheets.get(id);
366
+ const sheet = byId.get(id);
367
+ const lists = sheetParts(shared.sheets.get(id));
368
+ if (!here || !sheet || !lists) continue;
369
+ const fit = (axis, count) => {
370
+ const lines = axis === "row" ? here.rows : here.cols;
371
+ if (lines.ids.length < count) lines.ids.push(...ids.many(count - lines.ids.length));
372
+ else if (lines.ids.length > count) t.removed[axis].push(...lines.ids.splice(count));
373
+ else return;
374
+ lines.changed();
375
+ t.lines[axis] = true;
376
+ };
377
+ if (t.lines.row || t.meta.has("rowCount")) fit("row", rowCountOf(sheet));
378
+ if (t.lines.col || t.meta.has("colCount")) fit("col", colCountOf(sheet));
379
+ if (t.lines.row) syncList(lists.rows, here.rows.ids);
380
+ if (t.lines.col) syncList(lists.cols, here.cols.ids);
381
+ const drop = (key) => {
382
+ lists.cells.delete(key);
383
+ lists.cells.delete(threadKey(key));
384
+ };
385
+ for (const row of t.removed.row) {
386
+ for (const col of here.cols.ids) drop(cellKey(row, col));
387
+ for (const col of t.removed.col) drop(cellKey(row, col));
388
+ lists.rowSizes.delete(row);
389
+ }
390
+ for (const col of t.removed.col) {
391
+ for (const row of here.rows.ids) drop(cellKey(row, col));
392
+ lists.colSizes.delete(col);
393
+ }
394
+ for (const key of t.cells) {
395
+ const { row, col } = cellAt(key, here);
396
+ if (row < 0 || col < 0) continue;
397
+ const [own, thread] = splitThread(sheet.cells[row]?.[col]);
398
+ if (thread !== lists.cells.get(threadKey(key))) {
399
+ if (thread) lists.cells.set(threadKey(key), thread);
400
+ else lists.cells.delete(threadKey(key));
401
+ }
402
+ const existing = lists.cells.get(key);
403
+ if (same(resolveCell(existing, here, layout), own)) continue;
404
+ const stored = anchorCell(own, here, layout);
405
+ if (isEmpty(stored)) lists.cells.delete(key);
406
+ else lists.cells.set(key, stored);
407
+ }
408
+ writeSizes(t.rowSizes, lists.rowSizes, here.rows, sheet.rowSizes);
409
+ writeSizes(t.colSizes, lists.colSizes, here.cols, sheet.colSizes);
410
+ for (const key of t.meta) {
411
+ if (!isMetaKey(key)) continue;
412
+ const value = sheet[key];
413
+ const existing = lists.meta.get(key);
414
+ if (key !== "name" && same(resolveMeta(key, existing, here, layout), value)) continue;
415
+ if (value === void 0) lists.meta.delete(key);
416
+ else {
417
+ const stored = anchorMeta(key, value, here, layout);
418
+ if (!same(existing, stored)) lists.meta.set(key, stored);
419
+ }
420
+ }
421
+ }
422
+ writeNamed(styles, shared.styles, tr.doc.styles);
423
+ writeNamed(types, shared.types, tr.doc.types);
424
+ for (const key of bookKeys) {
425
+ if (!isBookKey(key)) continue;
426
+ const value = tr.doc[key];
427
+ if (value === void 0) book.delete(key);
428
+ else if (!same(book.get(key), value)) book.set(key, value);
429
+ }
430
+ }
431
+ /** Steps that bring the grid in line with the shared workbook, as `next` lays it out. */
432
+ function applyShared(tr, shared, dirty, next) {
433
+ const before = layout;
434
+ const inserted = /* @__PURE__ */ new Set();
435
+ let refs = dirty.all || dirty.names;
436
+ const wanted = Array.from(next.sheets.keys());
437
+ if ((dirty.all || dirty.sheets || dirty.whole.size) && wanted.length) {
438
+ for (let i = tr.doc.sheets.length - 1; i >= 0; i--) {
439
+ const sheet = tr.doc.sheets[i];
440
+ const id = sheet.id;
441
+ if (id == null || dirty.all || dirty.whole.has(id) || !next.sheets.has(id)) tr.step({
442
+ type: "removeSheet",
443
+ sheet: sheetKey(sheet)
444
+ });
445
+ }
446
+ wanted.forEach((id, index) => {
447
+ const at = tr.indexOf(id);
448
+ if (at === -1) {
449
+ const here = next.sheets.get(id);
450
+ tr.step({
451
+ type: "insertSheet",
452
+ index,
453
+ data: readSheet(sheetParts(shared.sheets.get(id)), here, next)
454
+ });
455
+ inserted.add(id);
456
+ } else if (at !== index) tr.step({
457
+ type: "moveSheet",
458
+ sheet: id,
459
+ index
460
+ });
461
+ });
462
+ refs = true;
463
+ }
464
+ for (const [id, here] of next.sheets) {
465
+ if (inserted.has(id)) continue;
466
+ const d = dirty.bySheet.get(id);
467
+ const old = before.sheets.get(id);
468
+ const lists = sheetParts(shared.sheets.get(id));
469
+ if (!d || !old || !lists || tr.indexOf(id) === -1) continue;
470
+ if (d.lines.row && stepLines(tr, id, "row", old.rows.ids, here.rows.ids)) refs = true;
471
+ if (d.lines.col && stepLines(tr, id, "col", old.cols.ids, here.cols.ids)) refs = true;
472
+ const counts = {};
473
+ if (rowCountOf(tr.getSheet(id)) !== here.rows.ids.length) counts.rowCount = here.rows.ids.length;
474
+ if (colCountOf(tr.getSheet(id)) !== here.cols.ids.length) counts.colCount = here.cols.ids.length;
475
+ if (Object.keys(counts).length) tr.updateSheet(counts, id);
476
+ for (const key of new Set(Array.from(d.cells, cellOfKey))) {
477
+ const { row, col } = cellAt(key, here);
478
+ if (row < 0 || col < 0) continue;
479
+ const cell = withThread(resolveCell(lists.cells.get(key), here, next), lists.cells.get(threadKey(key)));
480
+ const at = {
481
+ sheet: id,
482
+ row,
483
+ col
484
+ };
485
+ if (!same(tr.getCell(at), cell)) tr.setCell(at, cell);
486
+ }
487
+ const sizes = (axis, keys, map, lines) => {
488
+ for (const line of keys) {
489
+ const at = lines.indexOf(line);
490
+ if (at < 0) continue;
491
+ const size = map.get(line);
492
+ if (tr.getSheet(id)[axis === "row" ? "rowSizes" : "colSizes"]?.[at] !== size) tr.setSize(axis, at, typeof size === "number" ? size : void 0, id);
493
+ }
494
+ };
495
+ sizes("row", d.rowSizes, lists.rowSizes, here.rows);
496
+ sizes("col", d.colSizes, lists.colSizes, here.cols);
497
+ const patch = {};
498
+ for (const key of d.meta) {
499
+ if (!isMetaKey(key)) continue;
500
+ const value = key === "name" ? here.name : resolveMeta(key, lists.meta.get(key), here, next);
501
+ if (!same(tr.getSheet(id)[key], value)) patch[key] = value;
502
+ }
503
+ if (Object.keys(patch).length) tr.updateSheet(patch, id);
504
+ }
505
+ if (refs) for (const [id, here] of next.sheets) {
506
+ if (inserted.has(id) || tr.indexOf(id) === -1) continue;
507
+ const lists = sheetParts(shared.sheets.get(id));
508
+ if (!lists) continue;
509
+ lists.cells.forEach((stored, key) => {
510
+ if (!hasRefs(stored)) return;
511
+ const { row, col } = cellAt(key, here);
512
+ if (row < 0 || col < 0) return;
513
+ const cell = withThread(resolveCell(stored, here, next), lists.cells.get(threadKey(key)));
514
+ const at = {
515
+ sheet: id,
516
+ row,
517
+ col
518
+ };
519
+ if (!same(tr.getCell(at), cell)) tr.setCell(at, cell);
520
+ });
521
+ const patch = {};
522
+ for (const key of ANCHORED_META) {
523
+ const value = resolveMeta(key, lists.meta.get(key), here, next);
524
+ if (!same(tr.getSheet(id)[key], value)) patch[key] = value;
525
+ }
526
+ if (Object.keys(patch).length) tr.updateSheet(patch, id);
527
+ }
528
+ const styleNames = dirty.all ? /* @__PURE__ */ new Set([...Object.keys(tr.doc.styles ?? {}), ...shared.styles.keys()]) : dirty.styles;
529
+ for (const name of styleNames) {
530
+ const value = shared.styles.get(name);
531
+ if (!same(tr.doc.styles?.[name], value)) tr.setStyle(name, value);
532
+ }
533
+ const typeNames = dirty.all ? /* @__PURE__ */ new Set([...Object.keys(tr.doc.types ?? {}), ...shared.types.keys()]) : dirty.types;
534
+ for (const name of typeNames) {
535
+ const value = shared.types.get(name);
536
+ if (!same(tr.doc.types?.[name], value)) tr.setType(name, value);
537
+ }
538
+ if (dirty.all) {
539
+ const patch = {};
540
+ const keys = /* @__PURE__ */ new Set([...Object.keys(tr.doc), ...book.keys()]);
541
+ for (const key of keys) {
542
+ if (!isBookKey(key)) continue;
543
+ const value = book.get(key);
544
+ if (!same(tr.doc[key], value)) patch[key] = value;
545
+ }
546
+ if (Object.keys(patch).length) tr.updateBook(patch);
547
+ }
548
+ }
549
+ /** Brings the grid in line with the shared workbook. */
550
+ function pull(dirty) {
551
+ parts = partsOf(book);
552
+ if (!context || !parts) return;
553
+ const shared = parts;
554
+ const next = readLayout(shared);
555
+ const meta = {
556
+ history: false,
557
+ origin: travelling ?? "remote"
558
+ };
559
+ const shown = context.sheet.value.id;
560
+ const selected = shown != null ? storeView(shown, context.selection.value) : void 0;
561
+ const kept = context.selection.value;
562
+ applying = true;
563
+ try {
564
+ context.transact((tr) => applyShared(tr, shared, dirty, next), meta);
565
+ } catch (error) {
566
+ console.error("[@dou-ui/sheet] could not apply a shared change; reading the workbook again", error);
567
+ try {
568
+ context.transact((tr) => applyShared(tr, shared, {
569
+ ...dirtyNone(),
570
+ all: true
571
+ }, next), meta);
572
+ } catch (again) {
573
+ console.error("[@dou-ui/sheet] could not read the shared workbook", again);
574
+ }
575
+ } finally {
576
+ applying = false;
577
+ }
578
+ layout = next;
579
+ if (dirty.all) {
580
+ const sheet = context;
581
+ nextTick(() => {
582
+ const now = sheet.selection.value;
583
+ if (now.active.row !== kept.active.row || now.active.col !== kept.active.col) sheet.select(kept);
584
+ });
585
+ } else if (selected && !travelling && context.sheet.value.id === selected.sheet) {
586
+ const view = readView(selected);
587
+ const current = context.selection.value;
588
+ if (view?.active && view.ranges.length && (view.active.row !== current.active.row || view.active.col !== current.active.col)) context.select(selectionOf(view.active, view.ranges));
589
+ }
590
+ revision.value++;
591
+ tidyLists(shared);
592
+ }
593
+ function tidyLists(shared) {
594
+ const repeated = [];
595
+ const check = (list, known) => {
596
+ if (list.length !== known.length) repeated.push([list, known]);
597
+ };
598
+ check(shared.order, Array.from(layout.sheets.keys()));
599
+ for (const here of layout.sheets.values()) {
600
+ const sheet = sheetParts(shared.sheets.get(here.id));
601
+ if (!sheet) continue;
602
+ check(sheet.rows, here.rows.ids);
603
+ check(sheet.cols, here.cols.ids);
604
+ }
605
+ if (!repeated.length) return;
606
+ queueMicrotask(() => ydoc.transact(() => {
607
+ for (const [list] of repeated) {
608
+ const items = list.toArray();
609
+ const first = /* @__PURE__ */ new Map();
610
+ items.forEach((id, i) => first.has(id) || first.set(id, i));
611
+ for (let i = items.length - 1; i >= 0; i--) if (first.get(items[i]) !== i) list.delete(i, 1);
612
+ }
613
+ }, untracked));
614
+ }
615
+ function run(action) {
616
+ if (!(action === "undo" ? undoManager.undoStack : undoManager.redoStack).length) return false;
617
+ travelling = action;
618
+ restore = void 0;
619
+ try {
620
+ undoManager[action]();
621
+ } finally {
622
+ travelling = null;
623
+ }
624
+ const popped = restore;
625
+ restore = void 0;
626
+ const view = popped && readView(popped);
627
+ if (view && context && popped) {
628
+ context.showSheet(popped.sheet);
629
+ if (view.active && view.ranges.length) context.select(selectionOf(view.active, view.ranges));
630
+ }
631
+ return true;
632
+ }
633
+ const peers = shallowRef([]);
634
+ const commentMap = options.comments;
635
+ const sharedThreads = commentMap;
636
+ const threads = shallowRef([]);
637
+ const readThreads = () => {
638
+ if (sharedThreads) threads.value = readSharedComments(sharedThreads);
639
+ };
640
+ readThreads();
641
+ return defineSheetExtension({
642
+ name: "collaboration",
643
+ priority: 0,
644
+ transaction(tr) {
645
+ if (applying || !parts) return;
646
+ tr.doc.sheets.forEach((sheet, index) => {
647
+ if (sheet.id != null) return;
648
+ let id = ids.next();
649
+ while (tr.indexOf(id) !== -1) id = ids.next();
650
+ tr.updateSheet({ id }, index);
651
+ });
652
+ const tracking = tr.meta.history !== false;
653
+ if (tracking && (!tr.meta.group || tr.meta.group !== lastGroup)) undoManager.stopCapturing();
654
+ if (tracking) lastGroup = tr.meta.group;
655
+ const shared = parts;
656
+ ydoc.transact(() => writeChanges(tr, shared), tracking ? tracked : untracked);
657
+ if (tr.steps.some((step) => step.type.endsWith("Lines") || step.type.endsWith("Sheet"))) revision.value++;
658
+ },
659
+ comments: sharedThreads ? () => ({
660
+ threads,
661
+ apply: (action) => applySharedCommentAction(sharedThreads, action, untracked)
662
+ }) : void 0,
663
+ history: () => ({
664
+ undo: () => run("undo"),
665
+ redo: () => run("redo"),
666
+ canUndo: () => undoManager.undoStack.length > 0,
667
+ canRedo: () => undoManager.redoStack.length > 0
668
+ }),
669
+ layers: awareness ? { below: [createPeers(peers)] } : void 0,
670
+ setup(sheet) {
671
+ context = sheet;
672
+ commentMap?.observe(readThreads);
673
+ readThreads();
674
+ parts = partsOf(book);
675
+ if (!parts) {
676
+ applying = true;
677
+ try {
678
+ sheet.transact((tr) => tr.doc.sheets.forEach((data, index) => {
679
+ if (data.id == null) tr.updateSheet({ id: ids.next() }, index);
680
+ }), { history: false });
681
+ } finally {
682
+ applying = false;
683
+ }
684
+ ydoc.transact(() => fillBook(book, sheet.doc.value), untracked);
685
+ parts = partsOf(book);
686
+ if (parts) layout = readLayout(parts);
687
+ } else {
688
+ layout = new SheetLayout();
689
+ pull({
690
+ ...dirtyNone(),
691
+ all: true
692
+ });
693
+ }
694
+ let dirty = dirtyNone();
695
+ const observe = (events, transaction) => {
696
+ if (transaction.origin === tracked || transaction.origin === untracked) return;
697
+ for (const event of events) collect(dirty, event);
698
+ };
699
+ const flush = () => {
700
+ if (!isDirty(dirty)) return;
701
+ const changes = dirty;
702
+ dirty = dirtyNone();
703
+ pull(changes);
704
+ };
705
+ book.observeDeep(observe);
706
+ ydoc.on("afterTransaction", flush);
707
+ let stopPresence;
708
+ let readPeers;
709
+ if (awareness) {
710
+ readPeers = () => {
711
+ const list = [];
712
+ awareness.getStates().forEach((state, client) => {
713
+ if (client === awareness.clientID) return;
714
+ const who = state.user;
715
+ const presence = state.sheet;
716
+ if (!who || !presence) return;
717
+ const view = readView(presence);
718
+ if (!view) return;
719
+ list.push({
720
+ client,
721
+ name: who.name ?? "",
722
+ color: who.color ?? "currentColor",
723
+ sheet: presence.sheet,
724
+ active: view.active,
725
+ ranges: view.ranges,
726
+ editing: !!presence.editing
727
+ });
728
+ });
729
+ peers.value = list;
730
+ };
731
+ readPeers();
732
+ awareness.on("change", readPeers);
733
+ const stopRevision = watch(revision, () => readPeers?.());
734
+ let arrived = false;
735
+ const stopShare = watch(() => [
736
+ sheet.focused.value,
737
+ sheet.sheet.value.id,
738
+ sheet.selection.value,
739
+ sheet.editor.cell.value,
740
+ revision.value
741
+ ], () => {
742
+ arrived ||= sheet.focused.value || !!sheet.editor.cell.value;
743
+ if (!arrived) return;
744
+ const id = sheet.sheet.value.id;
745
+ const view = id != null ? storeView(id, sheet.selection.value) : void 0;
746
+ awareness.setLocalStateField("sheet", view ? {
747
+ ...view,
748
+ editing: !!sheet.editor.cell.value
749
+ } : null);
750
+ }, { immediate: true });
751
+ stopPresence = () => {
752
+ stopRevision();
753
+ stopShare();
754
+ };
755
+ }
756
+ return () => {
757
+ commentMap?.unobserve(readThreads);
758
+ book.unobserveDeep(observe);
759
+ ydoc.off("afterTransaction", flush);
760
+ stopPresence?.();
761
+ if (readPeers) awareness?.off("change", readPeers);
762
+ awareness?.setLocalStateField("sheet", null);
763
+ context = void 0;
764
+ };
765
+ }
766
+ });
767
+ }
768
+ export { collaboration, collaborationColors, fillBook, readBook };
769
+
770
+ //# sourceMappingURL=index.js.map