@dxos/plugin-sheet 0.10.0 → 0.11.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 (227) hide show
  1. package/dist/lib/SheetPlugin.mjs +32 -0
  2. package/dist/lib/SheetPlugin.mjs.map +1 -0
  3. package/dist/lib/SheetPlugin.node.mjs +11 -0
  4. package/dist/lib/SheetPlugin.node.mjs.map +1 -0
  5. package/dist/lib/SheetPlugin.workerd.mjs +11 -0
  6. package/dist/lib/SheetPlugin.workerd.mjs.map +1 -0
  7. package/dist/lib/capabilities/node.mjs +10 -0
  8. package/dist/lib/capabilities/node.mjs.map +1 -0
  9. package/dist/lib/capabilities.mjs +16 -0
  10. package/dist/lib/capabilities.mjs.map +1 -0
  11. package/dist/lib/chunk-RangeList.mjs +47 -0
  12. package/dist/lib/chunk-RangeList.mjs.map +1 -0
  13. package/dist/lib/chunk-SheetArticle.mjs +58 -0
  14. package/dist/lib/chunk-SheetArticle.mjs.map +1 -0
  15. package/dist/lib/chunk-anchor-sort.mjs +18 -0
  16. package/dist/lib/chunk-anchor-sort.mjs.map +1 -0
  17. package/dist/lib/chunk-comment-config.mjs +18 -0
  18. package/dist/lib/chunk-comment-config.mjs.map +1 -0
  19. package/dist/lib/chunk-compute-graph-registry.mjs +24 -0
  20. package/dist/lib/chunk-compute-graph-registry.mjs.map +1 -0
  21. package/dist/lib/chunk-create-object.mjs +24 -0
  22. package/dist/lib/chunk-create-object.mjs.map +1 -0
  23. package/dist/lib/chunk-create.mjs +20 -0
  24. package/dist/lib/chunk-create.mjs.map +1 -0
  25. package/dist/lib/chunk-drop-axis.mjs +18 -0
  26. package/dist/lib/chunk-drop-axis.mjs.map +1 -0
  27. package/dist/lib/chunk-extensions.mjs +246 -0
  28. package/dist/lib/chunk-extensions.mjs.map +1 -0
  29. package/dist/lib/chunk-get-values.mjs +73 -0
  30. package/dist/lib/chunk-get-values.mjs.map +1 -0
  31. package/dist/lib/chunk-insert-axis.mjs +11 -0
  32. package/dist/lib/chunk-insert-axis.mjs.map +1 -0
  33. package/dist/lib/chunk-markdown-extension.mjs +22 -0
  34. package/dist/lib/chunk-markdown-extension.mjs.map +1 -0
  35. package/dist/lib/{neutral/chunk-WTSCOM64.mjs → chunk-meta.mjs} +20 -28
  36. package/dist/lib/chunk-meta.mjs.map +1 -0
  37. package/dist/lib/chunk-operation-handler.mjs +11 -0
  38. package/dist/lib/chunk-operation-handler.mjs.map +1 -0
  39. package/dist/lib/chunk-react-surface.mjs +27 -0
  40. package/dist/lib/chunk-react-surface.mjs.map +1 -0
  41. package/dist/lib/chunk-restore-axis.mjs +11 -0
  42. package/dist/lib/chunk-restore-axis.mjs.map +1 -0
  43. package/dist/lib/chunk-scroll-to-anchor.mjs +20 -0
  44. package/dist/lib/chunk-scroll-to-anchor.mjs.map +1 -0
  45. package/dist/lib/chunk-set-values.mjs +20 -0
  46. package/dist/lib/chunk-set-values.mjs.map +1 -0
  47. package/dist/lib/{neutral/skill-definition-U3KQCFOI.mjs → chunk-skill-definition.mjs} +6 -8
  48. package/dist/lib/chunk-skill-definition.mjs.map +1 -0
  49. package/dist/lib/chunk-state.mjs +27 -0
  50. package/dist/lib/chunk-state.mjs.map +1 -0
  51. package/dist/lib/chunk-thread-ranges.mjs +59 -0
  52. package/dist/lib/chunk-thread-ranges.mjs.map +1 -0
  53. package/dist/lib/chunk-types.mjs +355 -0
  54. package/dist/lib/chunk-types.mjs.map +1 -0
  55. package/dist/lib/chunk-undo-mappings.mjs +22 -0
  56. package/dist/lib/chunk-undo-mappings.mjs.map +1 -0
  57. package/dist/lib/components.mjs +1377 -0
  58. package/dist/lib/components.mjs.map +1 -0
  59. package/dist/lib/containers.mjs +8 -0
  60. package/dist/lib/containers.mjs.map +1 -0
  61. package/dist/lib/index.mjs +4 -0
  62. package/dist/lib/meta.mjs +2 -0
  63. package/dist/lib/operations/node.mjs +7 -0
  64. package/dist/lib/operations/node.mjs.map +1 -0
  65. package/dist/lib/operations.mjs +7 -0
  66. package/dist/lib/operations.mjs.map +1 -0
  67. package/dist/lib/plugin.mjs +9 -0
  68. package/dist/lib/plugin.mjs.map +1 -0
  69. package/dist/lib/skills.mjs +42 -0
  70. package/dist/lib/skills.mjs.map +1 -0
  71. package/dist/lib/testing.mjs +59 -0
  72. package/dist/lib/testing.mjs.map +1 -0
  73. package/dist/lib/translations.mjs +50 -0
  74. package/dist/lib/translations.mjs.map +1 -0
  75. package/dist/lib/types.mjs +2 -0
  76. package/dist/types/src/capabilities/anchor-sort.d.ts +1 -1
  77. package/dist/types/src/capabilities/compute-graph-registry.d.ts +1 -1
  78. package/dist/types/src/capabilities/create-object.d.ts +1 -1
  79. package/dist/types/src/capabilities/markdown-extension.d.ts +1 -1
  80. package/dist/types/src/capabilities/node.d.ts +7 -0
  81. package/dist/types/src/capabilities/node.d.ts.map +1 -0
  82. package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
  83. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  84. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  85. package/dist/types/src/capabilities/skill-definition.d.ts +1 -1
  86. package/dist/types/src/capabilities/state.d.ts +1 -1
  87. package/dist/types/src/capabilities/undo-mappings.d.ts +1 -1
  88. package/dist/types/src/components/ComputeGraph/ComputeGraphContext.d.ts +11 -0
  89. package/dist/types/src/components/ComputeGraph/ComputeGraphContext.d.ts.map +1 -0
  90. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +1 -10
  91. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -1
  92. package/dist/types/src/components/ComputeGraph/index.d.ts +1 -0
  93. package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
  94. package/dist/types/src/components/Sheet/Sheet.d.ts +4 -4
  95. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
  96. package/dist/types/src/components/SheetContent/SheetContent.d.ts +1 -1
  97. package/dist/types/src/components/SheetContent/SheetContent.d.ts.map +1 -1
  98. package/dist/types/src/components/SheetContent/SheetContent.stories.d.ts +1 -1
  99. package/dist/types/src/components/SheetRoot/SheetContext.d.ts +4 -0
  100. package/dist/types/src/components/SheetRoot/SheetContext.d.ts.map +1 -0
  101. package/dist/types/src/components/SheetRoot/SheetRoot.d.ts +0 -1
  102. package/dist/types/src/components/SheetRoot/SheetRoot.d.ts.map +1 -1
  103. package/dist/types/src/components/SheetRoot/index.d.ts +1 -0
  104. package/dist/types/src/components/SheetRoot/index.d.ts.map +1 -1
  105. package/dist/types/src/components/SheetStatusbar/SheetStatusbar.d.ts +1 -1
  106. package/dist/types/src/components/SheetStatusbar/SheetStatusbar.d.ts.map +1 -1
  107. package/dist/types/src/components/SheetToolbar/SheetToolbar.d.ts +1 -1
  108. package/dist/types/src/components/SheetToolbar/SheetToolbar.d.ts.map +1 -1
  109. package/dist/types/src/components/index.d.ts +1 -0
  110. package/dist/types/src/components/index.d.ts.map +1 -1
  111. package/dist/types/src/containers/RangeList/RangeList.d.ts +4 -1
  112. package/dist/types/src/containers/RangeList/RangeList.d.ts.map +1 -1
  113. package/dist/types/src/containers/SheetArticle/SheetArticle.d.ts +4 -5
  114. package/dist/types/src/containers/SheetArticle/SheetArticle.d.ts.map +1 -1
  115. package/dist/types/src/containers/SheetArticle/SheetArticle.stories.d.ts +4 -1
  116. package/dist/types/src/containers/SheetArticle/SheetArticle.stories.d.ts.map +1 -1
  117. package/dist/types/src/extensions/editor/sheet-extension.d.ts.map +1 -1
  118. package/dist/types/src/operations/node.d.ts +3 -0
  119. package/dist/types/src/operations/node.d.ts.map +1 -0
  120. package/dist/types/src/operations/scroll-to-anchor.d.ts.map +1 -1
  121. package/dist/types/src/plugin.d.ts +1 -1
  122. package/dist/types/src/plugin.d.ts.map +1 -1
  123. package/dist/types/src/testing/testing.d.ts +8 -2
  124. package/dist/types/src/testing/testing.d.ts.map +1 -1
  125. package/dist/types/src/types/SheetOperation.d.ts +1 -1
  126. package/dist/types/src/types/SheetOperation.d.ts.map +1 -1
  127. package/dist/types/tsconfig.tsbuildinfo +1 -1
  128. package/dx.config.ts +1 -0
  129. package/package.json +75 -67
  130. package/src/capabilities/node.ts +18 -0
  131. package/src/capabilities/{react-surface.tsx → react-surface.ts} +6 -18
  132. package/src/components/ComputeGraph/ComputeGraphContext.ts +35 -0
  133. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +2 -27
  134. package/src/components/ComputeGraph/compute-graph.stories.tsx +1 -1
  135. package/src/components/ComputeGraph/index.ts +2 -0
  136. package/src/components/Sheet/Sheet.tsx +1 -1
  137. package/src/components/SheetRoot/SheetContext.ts +19 -0
  138. package/src/components/SheetRoot/SheetRoot.tsx +2 -9
  139. package/src/components/SheetRoot/index.ts +2 -0
  140. package/src/components/SheetStatusbar/SheetStatusbar.tsx +1 -1
  141. package/src/components/SheetToolbar/SheetToolbar.tsx +9 -9
  142. package/src/components/index.ts +1 -0
  143. package/src/containers/RangeList/RangeList.tsx +2 -0
  144. package/src/containers/SheetArticle/SheetArticle.stories.tsx +15 -24
  145. package/src/containers/SheetArticle/SheetArticle.tsx +23 -11
  146. package/src/extensions/editor/sheet-extension.ts +61 -2
  147. package/src/integrations/thread-ranges.ts +4 -4
  148. package/src/operations/node.ts +18 -0
  149. package/src/operations/scroll-to-anchor.ts +3 -2
  150. package/src/plugin.ts +1 -1
  151. package/src/testing/testing.tsx +11 -5
  152. package/src/types/SheetOperation.ts +6 -2
  153. package/dist/lib/neutral/RangeList-EIJTFS7P.mjs +0 -53
  154. package/dist/lib/neutral/RangeList-EIJTFS7P.mjs.map +0 -7
  155. package/dist/lib/neutral/SheetArticle-IUPQYGUU.mjs +0 -34
  156. package/dist/lib/neutral/SheetArticle-IUPQYGUU.mjs.map +0 -7
  157. package/dist/lib/neutral/SheetPlugin.mjs +0 -61
  158. package/dist/lib/neutral/SheetPlugin.mjs.map +0 -7
  159. package/dist/lib/neutral/SheetPlugin.node.mjs +0 -27
  160. package/dist/lib/neutral/SheetPlugin.node.mjs.map +0 -7
  161. package/dist/lib/neutral/SheetPlugin.workerd.mjs +0 -21
  162. package/dist/lib/neutral/SheetPlugin.workerd.mjs.map +0 -7
  163. package/dist/lib/neutral/anchor-sort-2POWTKTD.mjs +0 -22
  164. package/dist/lib/neutral/anchor-sort-2POWTKTD.mjs.map +0 -7
  165. package/dist/lib/neutral/capabilities/index.mjs +0 -27
  166. package/dist/lib/neutral/capabilities/index.mjs.map +0 -7
  167. package/dist/lib/neutral/chunk-ERHMBRSU.mjs +0 -234
  168. package/dist/lib/neutral/chunk-ERHMBRSU.mjs.map +0 -7
  169. package/dist/lib/neutral/chunk-HEN74ZWI.mjs +0 -83
  170. package/dist/lib/neutral/chunk-HEN74ZWI.mjs.map +0 -7
  171. package/dist/lib/neutral/chunk-HY4DM35G.mjs +0 -466
  172. package/dist/lib/neutral/chunk-HY4DM35G.mjs.map +0 -7
  173. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
  174. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
  175. package/dist/lib/neutral/chunk-TDGEOMRG.mjs +0 -8
  176. package/dist/lib/neutral/chunk-TDGEOMRG.mjs.map +0 -7
  177. package/dist/lib/neutral/chunk-WTSCOM64.mjs.map +0 -7
  178. package/dist/lib/neutral/comment-config-4CIQFYM2.mjs +0 -22
  179. package/dist/lib/neutral/comment-config-4CIQFYM2.mjs.map +0 -7
  180. package/dist/lib/neutral/components/index.mjs +0 -1552
  181. package/dist/lib/neutral/components/index.mjs.map +0 -7
  182. package/dist/lib/neutral/compute-graph-registry-YYINTFC2.mjs +0 -26
  183. package/dist/lib/neutral/compute-graph-registry-YYINTFC2.mjs.map +0 -7
  184. package/dist/lib/neutral/containers/index.mjs +0 -11
  185. package/dist/lib/neutral/containers/index.mjs.map +0 -7
  186. package/dist/lib/neutral/create-I3TKMPQO.mjs +0 -30
  187. package/dist/lib/neutral/create-I3TKMPQO.mjs.map +0 -7
  188. package/dist/lib/neutral/create-object-5WEY5XZJ.mjs +0 -27
  189. package/dist/lib/neutral/create-object-5WEY5XZJ.mjs.map +0 -7
  190. package/dist/lib/neutral/drop-axis-JPFU5CJO.mjs +0 -23
  191. package/dist/lib/neutral/drop-axis-JPFU5CJO.mjs.map +0 -7
  192. package/dist/lib/neutral/get-values-7YWQTH65.mjs +0 -92
  193. package/dist/lib/neutral/get-values-7YWQTH65.mjs.map +0 -7
  194. package/dist/lib/neutral/index.mjs +0 -66
  195. package/dist/lib/neutral/index.mjs.map +0 -7
  196. package/dist/lib/neutral/insert-axis-WD6ZC3UA.mjs +0 -16
  197. package/dist/lib/neutral/insert-axis-WD6ZC3UA.mjs.map +0 -7
  198. package/dist/lib/neutral/markdown-extension-HTJDICGT.mjs +0 -28
  199. package/dist/lib/neutral/markdown-extension-HTJDICGT.mjs.map +0 -7
  200. package/dist/lib/neutral/meta.json +0 -1
  201. package/dist/lib/neutral/meta.mjs +0 -8
  202. package/dist/lib/neutral/meta.mjs.map +0 -7
  203. package/dist/lib/neutral/operation-handler-TB6LFV2H.mjs +0 -13
  204. package/dist/lib/neutral/operation-handler-TB6LFV2H.mjs.map +0 -7
  205. package/dist/lib/neutral/operations/index.mjs +0 -8
  206. package/dist/lib/neutral/operations/index.mjs.map +0 -7
  207. package/dist/lib/neutral/plugin.mjs +0 -16
  208. package/dist/lib/neutral/plugin.mjs.map +0 -7
  209. package/dist/lib/neutral/react-surface-TJT6F2E4.mjs +0 -40
  210. package/dist/lib/neutral/react-surface-TJT6F2E4.mjs.map +0 -7
  211. package/dist/lib/neutral/restore-axis-RLPX7P3G.mjs +0 -16
  212. package/dist/lib/neutral/restore-axis-RLPX7P3G.mjs.map +0 -7
  213. package/dist/lib/neutral/scroll-to-anchor-6FJJQWZC.mjs +0 -33
  214. package/dist/lib/neutral/scroll-to-anchor-6FJJQWZC.mjs.map +0 -7
  215. package/dist/lib/neutral/set-values-5DVOVLJH.mjs +0 -30
  216. package/dist/lib/neutral/set-values-5DVOVLJH.mjs.map +0 -7
  217. package/dist/lib/neutral/skill-definition-U3KQCFOI.mjs.map +0 -7
  218. package/dist/lib/neutral/state-HPA27MX2.mjs +0 -29
  219. package/dist/lib/neutral/state-HPA27MX2.mjs.map +0 -7
  220. package/dist/lib/neutral/testing/index.mjs +0 -103
  221. package/dist/lib/neutral/testing/index.mjs.map +0 -7
  222. package/dist/lib/neutral/translations.mjs +0 -56
  223. package/dist/lib/neutral/translations.mjs.map +0 -7
  224. package/dist/lib/neutral/types/index.mjs +0 -58
  225. package/dist/lib/neutral/types/index.mjs.map +0 -7
  226. package/dist/lib/neutral/undo-mappings-O75AYIRG.mjs +0 -31
  227. package/dist/lib/neutral/undo-mappings-O75AYIRG.mjs.map +0 -7
@@ -0,0 +1,246 @@
1
+ import { RANGE_NOTATION } from "@dxos/compute-hyperformula";
2
+ import "@dxos/invariant";
3
+ import "@dxos/async";
4
+ import { HighlightStyle, syntaxHighlighting } from "@codemirror/language";
5
+ import { StateEffect } from "@codemirror/state";
6
+ import { ViewPlugin, keymap } from "@codemirror/view";
7
+ import { singleValueFacet } from "@dxos/ui-editor";
8
+ import { acceptCompletion, autocompletion, completionStatus, startCompletion } from "@codemirror/autocomplete";
9
+ import { tags } from "@lezer/highlight";
10
+ import { spreadsheet } from "codemirror-lang-spreadsheet";
11
+ import { mx } from "@dxos/ui-theme";
12
+ StateEffect.define();
13
+ var computeGraphFacet = singleValueFacet();
14
+ //#endregion
15
+ //#region src/extensions/editor/sheet-extension.ts
16
+ /**
17
+ * https://codemirror.net/examples/styling
18
+ * https://lezer.codemirror.net/docs/ref/#highlight
19
+ * https://github.com/luizzappa/codemirror-lang-spreadsheet/blob/main/src/index.ts#L28 (mapping)
20
+ */
21
+ var highlightStyles = HighlightStyle.define([
22
+ {
23
+ tag: tags.name,
24
+ class: "text-accent-text"
25
+ },
26
+ {
27
+ tag: tags.tagName,
28
+ class: "text-pink-text"
29
+ },
30
+ {
31
+ tag: tags.number,
32
+ class: "text-teal-text"
33
+ },
34
+ {
35
+ tag: tags.bool,
36
+ class: "text-teal-text"
37
+ },
38
+ {
39
+ tag: tags.string,
40
+ class: "text-teal-text"
41
+ },
42
+ {
43
+ tag: tags.invalid,
44
+ class: "text-un-accent"
45
+ }
46
+ ]);
47
+ var languageFacet = singleValueFacet();
48
+ /**
49
+ * Spreadsheet formula extension and parser.
50
+ * https://github.com/luizzappa/codemirror-lang-spreadsheet
51
+ * https://github.com/luizzappa/codemirror-app-spreadsheet/blob/master/src/editor.ts
52
+ * https://github.com/codemirror/lang-example
53
+ * https://hyperformula.handsontable.com/guide/key-concepts.html#grammar
54
+ */
55
+ var sheetExtension = ({ debug, functions = [] }) => {
56
+ const { extension, language } = spreadsheet({
57
+ idiom: "en-US",
58
+ decimalSeparator: "."
59
+ });
60
+ const createCompletion = (name) => {
61
+ const { section = "Custom", description, syntax } = functions.find((value) => value.name === name) ?? {};
62
+ return {
63
+ section,
64
+ label: name,
65
+ info: () => {
66
+ if (!description && !syntax) return null;
67
+ const root = document.createElement("div");
68
+ root.className = "flex flex-col gap-2 text-sm";
69
+ const title = document.createElement("h2");
70
+ title.innerText = name;
71
+ title.className = "text-lg font-mono text-accent-text";
72
+ root.appendChild(title);
73
+ if (description) {
74
+ const info = document.createElement("p");
75
+ info.innerText = description;
76
+ info.className = "text-subdued";
77
+ root.appendChild(info);
78
+ }
79
+ if (syntax) {
80
+ const detail = document.createElement("pre");
81
+ detail.innerText = syntax;
82
+ detail.className = "whitespace-pre-wrap text-green-text";
83
+ root.appendChild(detail);
84
+ }
85
+ return root;
86
+ },
87
+ apply: (view, completion, from, to) => {
88
+ const insertParens = to === view.state.doc.toString().length;
89
+ view.dispatch(view.state.update({
90
+ changes: {
91
+ from,
92
+ to,
93
+ insert: completion.label + (insertParens ? "()" : "")
94
+ },
95
+ selection: { anchor: from + completion.label.length + 1 }
96
+ }));
97
+ }
98
+ };
99
+ };
100
+ return [
101
+ extension,
102
+ languageFacet.of(language),
103
+ language.data.of({ autocomplete: (context) => {
104
+ if (context.state.doc.toString()[0] !== "=") return null;
105
+ const match = context.matchBefore(/\w*/);
106
+ if (!match || match.from === match.to) return null;
107
+ const text = match.text.toUpperCase();
108
+ if (!context.explicit && match.text.length < 2) return null;
109
+ return {
110
+ from: match.from,
111
+ options: functions?.filter(({ name }) => name.startsWith(text)).map(({ name }) => createCompletion(name)) ?? []
112
+ };
113
+ } }),
114
+ syntaxHighlighting(highlightStyles),
115
+ anchorCompletionTooltip,
116
+ autocompletion({
117
+ aboveCursor: false,
118
+ defaultKeymap: true,
119
+ activateOnTyping: true,
120
+ closeOnBlur: !debug,
121
+ icons: false,
122
+ tooltipClass: () => mx("-m-0! border border-h-0! [&>ul]:min-w-[198px]!", "[&>ul>li[aria-selected]]:bg-accent-bg!", "border-separator")
123
+ }),
124
+ keymap.of([{
125
+ key: "Tab",
126
+ run: (view) => {
127
+ return completionStatus(view.state) === "active" ? acceptCompletion(view) : startCompletion(view);
128
+ }
129
+ }])
130
+ ];
131
+ };
132
+ /**
133
+ * Tracks the currently active cell within a formula and provides a callback to modify it.
134
+ */
135
+ var rangeExtension = ({ onInit, onStateChange }) => {
136
+ let view;
137
+ let activeRange;
138
+ const notifier = { setRange: (range) => {
139
+ if (activeRange) view.dispatch(view.state.update({
140
+ changes: {
141
+ ...activeRange,
142
+ insert: range.toString()
143
+ },
144
+ selection: { anchor: activeRange.from + range.length }
145
+ }));
146
+ view.focus();
147
+ } };
148
+ return ViewPlugin.fromClass(class {
149
+ constructor(_view) {
150
+ view = _view;
151
+ onInit?.(notifier);
152
+ }
153
+ update(view) {
154
+ const { anchor } = view.state.selection.ranges[0];
155
+ activeRange = void 0;
156
+ const { topNode } = view.state.facet(languageFacet).parser.parse(view.state.doc.toString());
157
+ visitTree(topNode, ({ type, from, to }) => {
158
+ if (from <= anchor && to >= anchor) switch (type.name) {
159
+ case "Function":
160
+ activeRange = {
161
+ from: to,
162
+ to
163
+ };
164
+ break;
165
+ case "CloseParen":
166
+ activeRange = {
167
+ from,
168
+ to: from
169
+ };
170
+ break;
171
+ case "RangeToken":
172
+ case "CellToken":
173
+ activeRange = {
174
+ from,
175
+ to
176
+ };
177
+ return true;
178
+ }
179
+ return false;
180
+ });
181
+ if (!activeRange && view.state.doc.toString()[0] === "=") {
182
+ const str = view.state.doc.sliceString(1);
183
+ if (RANGE_NOTATION.test(str)) activeRange = {
184
+ from: 1,
185
+ to: str.length + 1
186
+ };
187
+ else activeRange = {
188
+ from: str.length + 1,
189
+ to: str.length + 1
190
+ };
191
+ }
192
+ onStateChange?.({ activeRange: activeRange ? view.state.doc.sliceString(activeRange.from, activeRange.to) : void 0 });
193
+ }
194
+ });
195
+ };
196
+ /**
197
+ * Lezer parse result visitor.
198
+ */
199
+ var visitTree = (node, callback) => {
200
+ if (callback(node)) return true;
201
+ for (let child = node.firstChild; child !== null; child = child.nextSibling) if (visitTree(child, callback)) return true;
202
+ return false;
203
+ };
204
+ /**
205
+ * Pins the completion tooltip to the editing cell rather than to the cursor.
206
+ *
207
+ * CodeMirror anchors it at the completion's start offset — a few pixels in from the cell's edge, and
208
+ * further in the longer the expression before the function name — overlapping the cell's lower
209
+ * border. In a grid the cell is the meaningful anchor.
210
+ *
211
+ * Driven by a DOM observer rather than the plugin's `update`: CodeMirror creates and positions the
212
+ * tooltip in its measure phase, which runs *after* the update, so an update-time correction either
213
+ * finds no tooltip or is immediately overwritten. Which side it opens on is still CodeMirror's call,
214
+ * so a tooltip near the bottom of the window still flips above the cell.
215
+ */
216
+ var anchorCompletionTooltip = ViewPlugin.fromClass(class {
217
+ _view;
218
+ _observer = new MutationObserver(() => this._pin());
219
+ constructor(_view) {
220
+ this._view = _view;
221
+ this._observer.observe(_view.dom, {
222
+ childList: true,
223
+ subtree: true,
224
+ attributes: true,
225
+ attributeFilter: ["style", "class"]
226
+ });
227
+ }
228
+ destroy() {
229
+ this._observer.disconnect();
230
+ }
231
+ /** Idempotent: writing values it already holds would retrigger the observer. */
232
+ _pin() {
233
+ const tooltip = this._view.dom.querySelector(".cm-tooltip-autocomplete");
234
+ if (!tooltip) return;
235
+ const cell = (this._view.dom.closest(".dx-grid__cell-editor") ?? this._view.dom).getBoundingClientRect();
236
+ const left = cell.left;
237
+ const top = tooltip.classList.contains("cm-tooltip-below") ? cell.bottom : cell.top - tooltip.getBoundingClientRect().height;
238
+ if (Math.abs(Number.parseFloat(tooltip.style.left || "0") - left) < .5 && Math.abs(Number.parseFloat(tooltip.style.top || "0") - top) < .5) return;
239
+ tooltip.style.left = `${left}px`;
240
+ tooltip.style.top = `${top}px`;
241
+ }
242
+ });
243
+ //#endregion
244
+ export { sheetExtension as n, computeGraphFacet as r, rangeExtension as t };
245
+
246
+ //# sourceMappingURL=chunk-extensions.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-extensions.mjs","names":[],"sources":["../../src/extensions/compute.ts","../../src/extensions/editor/sheet-extension.ts"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport {\n type EditorState,\n type Extension,\n type RangeSet,\n RangeSetBuilder,\n StateEffect,\n StateField,\n type Transaction,\n} from '@codemirror/state';\nimport { Decoration, EditorView, ViewPlugin, WidgetType } from '@codemirror/view';\n\nimport { type CleanupFn, debounce } from '@dxos/async';\nimport {\n type CellAddress,\n type CellScalarValue,\n type ComputeGraph,\n type ComputeNode,\n createSheetName,\n} from '@dxos/compute-hyperformula';\nimport { invariant } from '@dxos/invariant';\nimport { documentId, singleValueFacet } from '@dxos/ui-editor';\n\nconst LANGUAGE_TAG = 'dx';\n\n// TODO(burdon): Create marker just for our decorator?\nconst updateAllDecorations = StateEffect.define<void>();\n\nexport const computeGraphFacet = singleValueFacet<ComputeGraph>();\n\nexport type ComputeOptions = {};\n\nexport const compute = (_options: ComputeOptions = {}): Extension => {\n let computeNode: ComputeNode | undefined;\n\n const update = (state: EditorState, current?: RangeSet<Decoration>) => {\n const builder = new RangeSetBuilder<Decoration>();\n if (computeNode) {\n computeNode.clear();\n syntaxTree(state).iterate({\n enter: (node) => {\n switch (node.name) {\n case 'FencedCode': {\n const cursor = state.selection.main.head;\n if (state.readOnly || cursor < node.from || cursor > node.to) {\n const info = node.node.getChild('CodeInfo');\n if (info) {\n const type = state.sliceDoc(info.from, info.to);\n const text = node.node.getChild('CodeText');\n if (type === LANGUAGE_TAG && text) {\n const formula = state.sliceDoc(text.from, text.to);\n const iter = current?.iter(node.node.from);\n if (iter?.value && iter?.value.spec.formula === formula) {\n // Add existing widget.\n builder.add(node.from, node.to, iter.value);\n } else {\n // TODO(burdon): Create ordered list of cells on each decoration run.\n const cell: CellAddress = { col: node.node.from, row: 0 };\n invariant(computeNode);\n // NOTE: This triggers re-render (below).\n computeNode.setValue(cell, formula);\n const value = computeNode.getValue(cell);\n builder.add(\n node.from,\n node.to,\n Decoration.replace({\n widget: new ComputeWidget(formula, value),\n formula,\n }),\n );\n }\n }\n }\n }\n\n break;\n }\n }\n },\n });\n }\n\n return builder.finish();\n };\n\n return [\n ViewPlugin.fromClass(\n class {\n // Graph subscription.\n private _subscription?: CleanupFn;\n constructor(view: EditorView) {\n const id = view.state.facet(documentId);\n const computeGraph = view.state.facet(computeGraphFacet);\n if (id && computeGraph) {\n queueMicrotask(async () => {\n computeNode = computeGraph.getOrCreateNode(createSheetName({ type: '', id }));\n await computeNode.open();\n\n // Trigger re-render if values updated.\n // TODO(burdon): Trigger only if formula value updated (currently triggered during render).\n this._subscription = computeNode.update.on(\n debounce(({ type, ...rest }) => {\n if (type === 'valuesUpdated') {\n view.dispatch({\n effects: updateAllDecorations.of(),\n });\n }\n }, 250),\n );\n });\n }\n }\n\n destroy() {\n this._subscription?.();\n void computeNode?.close();\n computeNode = undefined;\n }\n },\n ),\n\n StateField.define<RangeSet<Decoration>>({\n create: (state) => update(state),\n update: (rangeSet: RangeSet<Decoration>, tr: Transaction) => update(tr.state, rangeSet),\n provide: (field) => EditorView.decorations.from(field),\n }),\n ];\n};\n\n// TODO(burdon): Click to edit.\nclass ComputeWidget extends WidgetType {\n constructor(\n private readonly formula: string,\n private readonly value: CellScalarValue,\n ) {\n super();\n }\n\n override toDOM(_view: EditorView): HTMLDivElement {\n const div = document.createElement('div');\n div.setAttribute('title', this.formula);\n div.innerText = String(this.value);\n return div;\n }\n}\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport {\n type Completion,\n type CompletionContext,\n type CompletionResult,\n acceptCompletion,\n autocompletion,\n completionStatus,\n startCompletion,\n} from '@codemirror/autocomplete';\nimport { HighlightStyle, type Language, syntaxHighlighting } from '@codemirror/language';\nimport { type Extension } from '@codemirror/state';\nimport { type EditorView, ViewPlugin, type ViewUpdate, keymap } from '@codemirror/view';\nimport { type SyntaxNode } from '@lezer/common';\nimport { tags } from '@lezer/highlight';\nimport { spreadsheet } from 'codemirror-lang-spreadsheet';\n\nimport { type FunctionDefinition } from '@dxos/compute-hyperformula';\nimport { RANGE_NOTATION } from '@dxos/compute-hyperformula';\nimport { singleValueFacet } from '@dxos/ui-editor';\nimport { mx } from '@dxos/ui-theme';\n\n/**\n * https://codemirror.net/examples/styling\n * https://lezer.codemirror.net/docs/ref/#highlight\n * https://github.com/luizzappa/codemirror-lang-spreadsheet/blob/main/src/index.ts#L28 (mapping)\n */\n// TODO(burdon): Define light/dark.\nconst highlightStyles = HighlightStyle.define([\n // Function.\n {\n tag: tags.name,\n class: 'text-accent-text',\n },\n // Range.\n {\n tag: tags.tagName,\n class: 'text-pink-text',\n },\n // Values.\n {\n tag: tags.number,\n class: 'text-teal-text',\n },\n {\n tag: tags.bool,\n class: 'text-teal-text',\n },\n {\n tag: tags.string,\n class: 'text-teal-text',\n },\n // Error.\n {\n tag: tags.invalid,\n class: 'text-un-accent',\n },\n]);\n\nconst languageFacet = singleValueFacet<Language>();\n\nexport type SheetExtensionOptions = {\n debug?: boolean;\n functions?: FunctionDefinition[];\n};\n\n/**\n * Spreadsheet formula extension and parser.\n * https://github.com/luizzappa/codemirror-lang-spreadsheet\n * https://github.com/luizzappa/codemirror-app-spreadsheet/blob/master/src/editor.ts\n * https://github.com/codemirror/lang-example\n * https://hyperformula.handsontable.com/guide/key-concepts.html#grammar\n */\nexport const sheetExtension = ({ debug, functions = [] }: SheetExtensionOptions): Extension => {\n const { extension, language } = spreadsheet({\n idiom: 'en-US',\n decimalSeparator: '.',\n });\n\n const createCompletion = (name: string) => {\n const { section = 'Custom', description, syntax } = functions.find((value) => value.name === name) ?? {};\n\n return {\n section,\n label: name,\n info: () => {\n if (!description && !syntax) {\n return null;\n }\n\n // TODO(burdon): Standardize color styles.\n const root = document.createElement('div');\n root.className = 'flex flex-col gap-2 text-sm';\n\n const title = document.createElement('h2');\n title.innerText = name;\n title.className = 'text-lg font-mono text-accent-text';\n root.appendChild(title);\n\n if (description) {\n const info = document.createElement('p');\n info.innerText = description;\n info.className = 'text-subdued';\n root.appendChild(info);\n }\n\n if (syntax) {\n const detail = document.createElement('pre');\n detail.innerText = syntax;\n detail.className = 'whitespace-pre-wrap text-green-text';\n root.appendChild(detail);\n }\n\n return root;\n },\n apply: (view, completion, from, to) => {\n const insertParens = to === view.state.doc.toString().length;\n view.dispatch(\n view.state.update({\n changes: {\n from,\n to,\n insert: completion.label + (insertParens ? '()' : ''),\n },\n selection: {\n anchor: from + completion.label.length + 1,\n },\n }),\n );\n },\n } satisfies Completion;\n };\n\n return [\n extension,\n languageFacet.of(language),\n language.data.of({\n autocomplete: (context: CompletionContext): CompletionResult | null => {\n if (context.state.doc.toString()[0] !== '=') {\n return null;\n }\n const match = context.matchBefore(/\\w*/);\n if (!match || match.from === match.to) {\n return null;\n }\n\n const text = match.text.toUpperCase();\n if (!context.explicit && match.text.length < 2) {\n return null;\n }\n\n return {\n from: match.from,\n options:\n functions?.filter(({ name }) => name.startsWith(text)).map(({ name }) => createCompletion(name)) ?? [],\n };\n },\n }),\n\n syntaxHighlighting(highlightStyles),\n anchorCompletionTooltip,\n autocompletion({\n aboveCursor: false,\n defaultKeymap: true,\n activateOnTyping: true,\n closeOnBlur: !debug,\n icons: false,\n // Cosmetics only. The tooltip is `position: fixed` and CodeMirror computes its coordinates from\n // the cursor, so overriding `left`/`top` here measures them against the viewport instead of the\n // cell — which pinned the completion list to the top-left corner of the window.\n tooltipClass: () =>\n mx(\n '-m-0! border border-h-0! [&>ul]:min-w-[198px]!',\n '[&>ul>li[aria-selected]]:bg-accent-bg!',\n 'border-separator',\n ),\n }),\n keymap.of([\n {\n key: 'Tab',\n run: (view) => {\n return completionStatus(view.state) === 'active' ? acceptCompletion(view) : startCompletion(view);\n },\n },\n ]),\n\n // Parsing.\n // StateField.define({\n // create: (state) => {},\n // update: (value, tr) => {\n // log.info('update');\n // syntaxTree(tr.state).iterate({\n // enter: ({ type, from, to }) => {\n // log.info('node', { type: type.name, from, to });\n // },\n // });\n // },\n // }),\n ];\n};\n\nexport type SelectionRange = { from: number; to: number };\n\nexport interface RangeController {\n setRange(range: string): void;\n}\n\nexport type RangeExtensionOptions = {\n /**\n * Provides controller callback when extension is initialized.\n */\n onInit?: (controller: RangeController) => void;\n /**\n * Called when the active range changes.\n * @param state The current state.\n * @param state.activeRange undefined if no range is active, otherwise a possibly partially defined range.\n */\n onStateChange?: (state: { activeRange: string | undefined }) => void;\n};\n\n/**\n * Tracks the currently active cell within a formula and provides a callback to modify it.\n */\nexport const rangeExtension = ({ onInit, onStateChange }: RangeExtensionOptions): Extension => {\n let view: EditorView;\n let activeRange: SelectionRange | undefined;\n\n // Called externally to provide current range.\n const notifier: RangeController = {\n setRange: (range: string) => {\n if (activeRange) {\n view.dispatch(\n view.state.update({\n changes: { ...activeRange, insert: range.toString() },\n selection: { anchor: activeRange.from + range.length },\n }),\n );\n }\n\n view.focus();\n },\n };\n\n return ViewPlugin.fromClass(\n class {\n constructor(_view: EditorView) {\n view = _view;\n onInit?.(notifier);\n }\n\n update(view: ViewUpdate) {\n const { anchor } = view.state.selection.ranges[0];\n\n // Find first Range or cell at cursor.\n activeRange = undefined;\n const language = view.state.facet(languageFacet);\n const { topNode } = language.parser.parse(view.state.doc.toString());\n visitTree(topNode, ({ type, from, to }) => {\n if (from <= anchor && to >= anchor) {\n switch (type.name) {\n case 'Function':\n // Mark but keep looking.\n activeRange = { from: to, to };\n break;\n\n case 'CloseParen':\n // Mark but keep looking.\n activeRange = { from, to: from };\n break;\n\n case 'RangeToken':\n case 'CellToken':\n activeRange = { from, to };\n return true;\n }\n }\n\n return false;\n });\n\n // Allow start of formula.\n if (!activeRange && view.state.doc.toString()[0] === '=') {\n const str = view.state.doc.sliceString(1);\n if (RANGE_NOTATION.test(str)) {\n activeRange = { from: 1, to: str.length + 1 };\n } else {\n activeRange = { from: str.length + 1, to: str.length + 1 };\n }\n }\n\n onStateChange?.({\n activeRange: activeRange ? view.state.doc.sliceString(activeRange.from, activeRange.to) : undefined,\n });\n }\n },\n );\n};\n\n/**\n * Lezer parse result visitor.\n */\nconst visitTree = (node: SyntaxNode, callback: (node: SyntaxNode) => boolean): boolean => {\n if (callback(node)) {\n return true;\n }\n\n for (let child = node.firstChild; child !== null; child = child.nextSibling) {\n if (visitTree(child, callback)) {\n return true;\n }\n }\n\n return false;\n};\n\n/**\n * Pins the completion tooltip to the editing cell rather than to the cursor.\n *\n * CodeMirror anchors it at the completion's start offset — a few pixels in from the cell's edge, and\n * further in the longer the expression before the function name — overlapping the cell's lower\n * border. In a grid the cell is the meaningful anchor.\n *\n * Driven by a DOM observer rather than the plugin's `update`: CodeMirror creates and positions the\n * tooltip in its measure phase, which runs *after* the update, so an update-time correction either\n * finds no tooltip or is immediately overwritten. Which side it opens on is still CodeMirror's call,\n * so a tooltip near the bottom of the window still flips above the cell.\n */\nconst anchorCompletionTooltip = ViewPlugin.fromClass(\n class {\n private readonly _observer = new MutationObserver(() => this._pin());\n\n constructor(private readonly _view: EditorView) {\n this._observer.observe(_view.dom, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['style', 'class'],\n });\n }\n\n destroy(): void {\n this._observer.disconnect();\n }\n\n /** Idempotent: writing values it already holds would retrigger the observer. */\n private _pin(): void {\n const tooltip = this._view.dom.querySelector<HTMLElement>('.cm-tooltip-autocomplete');\n if (!tooltip) {\n return;\n }\n\n // The cell editor's own box, not `view.dom` — the editor sits inset within it.\n const cell = (this._view.dom.closest('.dx-grid__cell-editor') ?? this._view.dom).getBoundingClientRect();\n const left = cell.left;\n const top = tooltip.classList.contains('cm-tooltip-below')\n ? cell.bottom\n : cell.top - tooltip.getBoundingClientRect().height;\n if (\n Math.abs(Number.parseFloat(tooltip.style.left || '0') - left) < 0.5 &&\n Math.abs(Number.parseFloat(tooltip.style.top || '0') - top) < 0.5\n ) {\n return;\n }\n\n tooltip.style.left = `${left}px`;\n tooltip.style.top = `${top}px`;\n }\n },\n);\n"],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { O as mapFormulaIndicesToRefs, S as addressToIndex, r as GetValues, x as addressFromIndex } from "./chunk-types.mjs";
2
+ import { Operation } from "@dxos/compute";
3
+ import { addressFromA1Notation, addressToA1Notation, isFormula } from "@dxos/compute-hyperformula";
4
+ import { Database } from "@dxos/echo";
5
+ import * as Effect from "effect/Effect";
6
+ //#region src/operations/get-values.ts
7
+ var handler = GetValues.pipe(Operation.withHandler(Effect.fn(function* ({ sheet: sheetRef, range }) {
8
+ const sheet = yield* Database.load(sheetRef);
9
+ let fromRow;
10
+ let fromCol;
11
+ let toRow;
12
+ let toCol;
13
+ if (range) {
14
+ const [fromPart, toPart = fromPart] = range.split(":");
15
+ const from = addressFromA1Notation(fromPart);
16
+ const to = addressFromA1Notation(toPart);
17
+ fromRow = from.row;
18
+ fromCol = from.col;
19
+ toRow = to.row;
20
+ toCol = to.col;
21
+ } else {
22
+ let minRow = Infinity;
23
+ let minCol = Infinity;
24
+ let maxRow = -1;
25
+ let maxCol = -1;
26
+ for (const key of Object.keys(sheet.cells)) {
27
+ const cellValue = sheet.cells[key]?.value;
28
+ if (cellValue !== void 0 && cellValue !== null) {
29
+ const { row, col } = addressFromIndex(sheet, key);
30
+ if (row < minRow) minRow = row;
31
+ if (row > maxRow) maxRow = row;
32
+ if (col < minCol) minCol = col;
33
+ if (col > maxCol) maxCol = col;
34
+ }
35
+ }
36
+ fromRow = minRow === Infinity ? 0 : minRow;
37
+ fromCol = minCol === Infinity ? 0 : minCol;
38
+ toRow = maxRow;
39
+ toCol = maxCol;
40
+ }
41
+ if (toRow < 0) return {
42
+ values: [],
43
+ range: "A1:A1"
44
+ };
45
+ const values = [];
46
+ for (let row = fromRow; row <= toRow; row++) {
47
+ const rowValues = [];
48
+ for (let col = fromCol; col <= toCol; col++) {
49
+ const idx = addressToIndex(sheet, {
50
+ row,
51
+ col
52
+ });
53
+ const rawValue = sheet.cells[idx]?.value ?? null;
54
+ const value = rawValue !== null && isFormula(String(rawValue)) ? mapFormulaIndicesToRefs(sheet, rawValue) : rawValue;
55
+ rowValues.push(value);
56
+ }
57
+ values.push(rowValues);
58
+ }
59
+ return {
60
+ values,
61
+ range: `${addressToA1Notation({
62
+ row: fromRow,
63
+ col: fromCol
64
+ })}:${addressToA1Notation({
65
+ row: toRow,
66
+ col: toCol
67
+ })}`
68
+ };
69
+ })));
70
+ //#endregion
71
+ export { handler as default };
72
+
73
+ //# sourceMappingURL=chunk-get-values.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-get-values.mjs","names":[],"sources":["../../src/operations/get-values.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Operation } from '@dxos/compute';\nimport { addressFromA1Notation, addressToA1Notation, isFormula } from '@dxos/compute-hyperformula';\nimport { Database } from '@dxos/echo';\n\nimport { SheetOperation, addressFromIndex, addressToIndex, mapFormulaIndicesToRefs } from '../types';\n\nconst handler: Operation.WithHandler<typeof SheetOperation.GetValues> = SheetOperation.GetValues.pipe(\n Operation.withHandler(\n Effect.fn(function* ({ sheet: sheetRef, range }) {\n const sheet = yield* Database.load(sheetRef);\n\n let fromRow: number;\n let fromCol: number;\n let toRow: number;\n let toCol: number;\n\n if (range) {\n const [fromPart, toPart = fromPart] = range.split(':');\n const from = addressFromA1Notation(fromPart);\n const to = addressFromA1Notation(toPart);\n fromRow = from.row;\n fromCol = from.col;\n toRow = to.row;\n toCol = to.col;\n } else {\n let minRow = Infinity;\n let minCol = Infinity;\n let maxRow = -1;\n let maxCol = -1;\n for (const key of Object.keys(sheet.cells)) {\n const cellValue = sheet.cells[key]?.value;\n if (cellValue !== undefined && cellValue !== null) {\n const { row, col } = addressFromIndex(sheet, key);\n if (row < minRow) {\n minRow = row;\n }\n if (row > maxRow) {\n maxRow = row;\n }\n if (col < minCol) {\n minCol = col;\n }\n if (col > maxCol) {\n maxCol = col;\n }\n }\n }\n fromRow = minRow === Infinity ? 0 : minRow;\n fromCol = minCol === Infinity ? 0 : minCol;\n toRow = maxRow;\n toCol = maxCol;\n }\n\n if (toRow < 0) {\n return { values: [], range: 'A1:A1' };\n }\n\n const values: (unknown | null)[][] = [];\n for (let row = fromRow; row <= toRow; row++) {\n const rowValues: (unknown | null)[] = [];\n for (let col = fromCol; col <= toCol; col++) {\n const idx = addressToIndex(sheet, { row, col });\n const rawValue = sheet.cells[idx]?.value ?? null;\n const value =\n rawValue !== null && isFormula(String(rawValue)) ? mapFormulaIndicesToRefs(sheet, rawValue) : rawValue;\n rowValues.push(value);\n }\n values.push(rowValues);\n }\n\n const actualRange = `${addressToA1Notation({ row: fromRow, col: fromCol })}:${addressToA1Notation({ row: toRow, col: toCol })}`;\n return { values, range: actualRange };\n }),\n ),\n);\n\nexport default handler;\n"],"mappings":";;;;;;AAYA,IAAM,UAAA,UAA2F,KAC/F,UAAU,YACR,OAAO,GAAG,WAAW,EAAE,OAAO,UAAU,SAAS;CAC/C,MAAM,QAAQ,OAAO,SAAS,KAAK,QAAQ;CAE3C,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CAEJ,IAAI,OAAO;EACT,MAAM,CAAC,UAAU,SAAS,YAAY,MAAM,MAAM,GAAG;EACrD,MAAM,OAAO,sBAAsB,QAAQ;EAC3C,MAAM,KAAK,sBAAsB,MAAM;EACvC,UAAU,KAAK;EACf,UAAU,KAAK;EACf,QAAQ,GAAG;EACX,QAAQ,GAAG;CACb,OAAO;EACL,IAAI,SAAS;EACb,IAAI,SAAS;EACb,IAAI,SAAS;EACb,IAAI,SAAS;EACb,KAAK,MAAM,OAAO,OAAO,KAAK,MAAM,KAAK,GAAG;GAC1C,MAAM,YAAY,MAAM,MAAM,IAAI,EAAE;GACpC,IAAI,cAAc,KAAA,KAAa,cAAc,MAAM;IACjD,MAAM,EAAE,KAAK,QAAQ,iBAAiB,OAAO,GAAG;IAChD,IAAI,MAAM,QACR,SAAS;IAEX,IAAI,MAAM,QACR,SAAS;IAEX,IAAI,MAAM,QACR,SAAS;IAEX,IAAI,MAAM,QACR,SAAS;GAEb;EACF;EACA,UAAU,WAAW,WAAW,IAAI;EACpC,UAAU,WAAW,WAAW,IAAI;EACpC,QAAQ;EACR,QAAQ;CACV;CAEA,IAAI,QAAQ,GACV,OAAO;EAAE,QAAQ,CAAC;EAAG,OAAO;CAAQ;CAGtC,MAAM,SAA+B,CAAC;CACtC,KAAK,IAAI,MAAM,SAAS,OAAO,OAAO,OAAO;EAC3C,MAAM,YAAgC,CAAC;EACvC,KAAK,IAAI,MAAM,SAAS,OAAO,OAAO,OAAO;GAC3C,MAAM,MAAM,eAAe,OAAO;IAAE;IAAK;GAAI,CAAC;GAC9C,MAAM,WAAW,MAAM,MAAM,IAAI,EAAE,SAAS;GAC5C,MAAM,QACJ,aAAa,QAAQ,UAAU,OAAO,QAAQ,CAAC,IAAI,wBAAwB,OAAO,QAAQ,IAAI;GAChG,UAAU,KAAK,KAAK;EACtB;EACA,OAAO,KAAK,SAAS;CACvB;CAGA,OAAO;EAAE;EAAQ,OAAO,GADD,oBAAoB;GAAE,KAAK;GAAS,KAAK;EAAQ,CAAC,EAAE,GAAG,oBAAoB;GAAE,KAAK;GAAO,KAAK;EAAM,CAAC;CACxF;AACtC,CAAC,CACH,CACF"}
@@ -0,0 +1,11 @@
1
+ import { i as InsertAxis } from "./chunk-types.mjs";
2
+ import { Operation } from "@dxos/compute";
3
+ import * as Effect from "effect/Effect";
4
+ //#region src/operations/insert-axis.ts
5
+ var handler = InsertAxis.pipe(Operation.withHandler(({ model, axis, index, count }) => Effect.sync(() => {
6
+ model[axis === "col" ? "insertColumns" : "insertRows"](index, count);
7
+ })));
8
+ //#endregion
9
+ export { handler as default };
10
+
11
+ //# sourceMappingURL=chunk-insert-axis.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-insert-axis.mjs","names":[],"sources":["../../src/operations/insert-axis.ts"],"sourcesContent":["//\n\nimport * as Effect from 'effect/Effect';\n// Copyright 2025 DXOS.org\n//\n\nimport { Operation } from '@dxos/compute';\n\nimport { SheetOperation } from '../types';\n\nconst handler: Operation.WithHandler<typeof SheetOperation.InsertAxis> = SheetOperation.InsertAxis.pipe(\n Operation.withHandler(({ model, axis, index, count }) =>\n Effect.sync(() => {\n model[axis === 'col' ? 'insertColumns' : 'insertRows'](index, count);\n }),\n ),\n);\n\nexport default handler;\n"],"mappings":";;;;AAUA,IAAM,UAAA,WAA6F,KACjG,UAAU,aAAa,EAAE,OAAO,MAAM,OAAO,YAC3C,OAAO,WAAW;CAChB,MAAM,SAAS,QAAQ,kBAAkB,aAAa,CAAC,OAAO,KAAK;AACrE,CAAC,CACH,CACF"}
@@ -0,0 +1,22 @@
1
+ import { r as computeGraphFacet } from "./chunk-extensions.mjs";
2
+ import { Capability } from "@dxos/app-framework";
3
+ import { SheetCapabilities } from "#types";
4
+ import * as Effect from "effect/Effect";
5
+ import { getSpace } from "@dxos/client/echo";
6
+ import { MarkdownCapabilities } from "@dxos/plugin-markdown/types";
7
+ //#region src/capabilities/markdown-extension.ts
8
+ var markdown_extension_default = Capability.makeModule(Effect.fnUntraced(function* () {
9
+ const capabilities = yield* Capability.Service;
10
+ return Capability.contributes(MarkdownCapabilities.ExtensionProvider, [({ document: doc }) => {
11
+ const computeGraphRegistry = capabilities.get(SheetCapabilities.ComputeGraphRegistry);
12
+ const space = getSpace(doc);
13
+ if (space) {
14
+ const computeGraph = computeGraphRegistry.getOrCreateGraph(space);
15
+ return computeGraphFacet.of(computeGraph);
16
+ }
17
+ }]);
18
+ }));
19
+ //#endregion
20
+ export { markdown_extension_default as default };
21
+
22
+ //# sourceMappingURL=chunk-markdown-extension.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-markdown-extension.mjs","names":[],"sources":["../../src/capabilities/markdown-extension.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { getSpace } from '@dxos/client/echo';\nimport { MarkdownCapabilities } from '@dxos/plugin-markdown/types';\n\nimport { SheetCapabilities } from '#types';\n\nimport { computeGraphFacet } from '../extensions';\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n // Get context for lazy capability access in callbacks.\n const capabilities = yield* Capability.Service;\n\n return Capability.contributes(MarkdownCapabilities.ExtensionProvider, [\n ({ document: doc }) => {\n const computeGraphRegistry = capabilities.get(SheetCapabilities.ComputeGraphRegistry);\n const space = getSpace(doc);\n if (space) {\n const computeGraph = computeGraphRegistry.getOrCreateGraph(space);\n return computeGraphFacet.of(computeGraph);\n }\n },\n ]);\n }),\n);\n"],"mappings":";;;;;;;AAcA,IAAA,6BAAe,WAAW,WACxB,OAAO,WAAW,aAAa;CAE7B,MAAM,eAAe,OAAO,WAAW;CAEvC,OAAO,WAAW,YAAY,qBAAqB,mBAAmB,EACnE,EAAE,UAAU,UAAU;EACrB,MAAM,uBAAuB,aAAa,IAAI,kBAAkB,oBAAoB;EACpF,MAAM,QAAQ,SAAS,GAAG;EAC1B,IAAI,OAAO;GACT,MAAM,eAAe,qBAAqB,iBAAiB,KAAK;GAChE,OAAO,kBAAkB,GAAG,YAAY;EAC1C;CACF,CACF,CAAC;AACH,CAAC,CACH"}
@@ -1,15 +1,12 @@
1
- // src/meta.ts
2
1
  import { Plugin } from "@dxos/app-framework";
3
-
4
- // dx.config.ts
5
2
  import { Config2 } from "@dxos/app-framework/config";
6
3
  import { trim } from "@dxos/util";
7
- var dx_config_default = Config2.make({
8
- plugin: {
9
- key: "org.dxos.plugin.sheet",
10
- name: "Sheet",
11
- author: "DXOS",
12
- description: trim`
4
+ //#region dx.config.ts
5
+ var dx_config_default = Config2.make({ plugin: {
6
+ key: "org.dxos.plugin.sheet",
7
+ name: "Sheet",
8
+ author: "DXOS",
9
+ description: trim`
13
10
  Full-featured spreadsheet for DXOS Composer backed by ECHO for local-first, real-time collaborative editing.
14
11
  Cells, row/column metadata, and range-based formatting are all stored as ECHO objects and replicated to peers instantly.
15
12
 
@@ -22,24 +19,19 @@ var dx_config_default = Config2.make({
22
19
  AI agents can invoke sheet operations — insert/drop axes, scroll to anchor, and read or write cell values — through
23
20
  the standard operations framework.
24
21
  `,
25
- icon: {
26
- key: "ph--grid-nine--regular",
27
- hue: "indigo"
28
- },
29
- source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-sheet",
30
- spec: "PLUGIN.mdl",
31
- screenshots: [
32
- {
33
- dark: "https://dxos.network/plugin-details-sheet-dark.png"
34
- }
35
- ]
36
- }
37
- });
38
-
39
- // src/meta.ts
22
+ icon: {
23
+ key: "ph--grid-nine--regular",
24
+ hue: "indigo"
25
+ },
26
+ source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-sheet",
27
+ spec: "PLUGIN.mdl",
28
+ screenshots: [{ dark: "https://dxos.network/plugin-details-sheet-dark.png" }],
29
+ tags: ["alpha"]
30
+ } });
31
+ //#endregion
32
+ //#region src/meta.ts
40
33
  var meta = Plugin.getMetaFromConfig(dx_config_default);
34
+ //#endregion
35
+ export { meta as t };
41
36
 
42
- export {
43
- meta
44
- };
45
- //# sourceMappingURL=chunk-WTSCOM64.mjs.map
37
+ //# sourceMappingURL=chunk-meta.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-meta.mjs","names":[],"sources":["../../dx.config.ts","../../src/meta.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport { Config2 } from '@dxos/app-framework/config';\nimport { trim } from '@dxos/util';\n\nexport default Config2.make({\n plugin: {\n key: 'org.dxos.plugin.sheet',\n name: 'Sheet',\n author: 'DXOS',\n description: trim`\n Full-featured spreadsheet for DXOS Composer backed by ECHO for local-first, real-time collaborative editing.\n Cells, row/column metadata, and range-based formatting are all stored as ECHO objects and replicated to peers instantly.\n\n Formula evaluation is powered by HyperFormula, providing over 400 built-in functions covering arithmetic, statistics,\n text manipulation, date/time, financial, and logical operations. Formulas are stored with internal cell indices and\n translated to A1-notation on display, keeping references stable across row and column insertions.\n\n The plugin integrates with plugin-markdown to expose formula results inside document fenced code blocks, and\n contributes anchor-navigation support so other plugins can scroll and highlight specific cell ranges by DXN reference.\n AI agents can invoke sheet operations — insert/drop axes, scroll to anchor, and read or write cell values — through\n the standard operations framework.\n `,\n icon: { key: 'ph--grid-nine--regular', hue: 'indigo' },\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-sheet',\n spec: 'PLUGIN.mdl',\n screenshots: [{ dark: 'https://dxos.network/plugin-details-sheet-dark.png' }],\n tags: ['alpha'],\n },\n});\n","//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\n\nimport config from '../dx.config';\n\nexport const meta = Plugin.getMetaFromConfig(config);\n"],"mappings":";;;;AAOA,IAAA,oBAAe,QAAQ,KAAK,EAC1B,QAAQ;CACN,KAAK;CACL,MAAM;CACN,QAAQ;CACR,aAAa,IAAI;;;;;;;;;;;;;CAajB,MAAM;EAAE,KAAK;EAA0B,KAAK;CAAS;CACrD,QAAQ;CACR,MAAM;CACN,aAAa,CAAC,EAAE,MAAM,qDAAqD,CAAC;CAC5E,MAAM,CAAC,OAAO;AAChB,EACF,CAAC;;;ACvBD,IAAa,OAAO,OAAO,kBAAkB,iBAAM"}
@@ -0,0 +1,11 @@
1
+ import { Capabilities, Capability } from "@dxos/app-framework";
2
+ import { SheetOperationHandlerSet } from "#operations";
3
+ import * as Effect from "effect/Effect";
4
+ //#region src/capabilities/operation-handler.ts
5
+ var operation_handler_default = Capability.makeModule(Effect.fnUntraced(function* () {
6
+ return Capability.contributes(Capabilities.OperationHandler, SheetOperationHandlerSet);
7
+ }));
8
+ //#endregion
9
+ export { operation_handler_default as default };
10
+
11
+ //# sourceMappingURL=chunk-operation-handler.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-operation-handler.mjs","names":[],"sources":["../../src/capabilities/operation-handler.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capabilities, Capability } from '@dxos/app-framework';\nimport type { OperationHandlerSet } from '@dxos/compute';\n\nimport { SheetOperationHandlerSet } from '#operations';\n\nexport default Capability.makeModule<OperationHandlerSet.OperationHandlerSet>(\n Effect.fnUntraced(function* () {\n return Capability.contributes(Capabilities.OperationHandler, SheetOperationHandlerSet);\n }),\n);\n"],"mappings":";;;;AAWA,IAAA,4BAAe,WAAW,WACxB,OAAO,WAAW,aAAa;CAC7B,OAAO,WAAW,YAAY,aAAa,kBAAkB,wBAAwB;AACvF,CAAC,CACH"}
@@ -0,0 +1,27 @@
1
+ import { Capabilities, Capability } from "@dxos/app-framework";
2
+ import { Obj } from "@dxos/echo";
3
+ import { Sheet } from "#types";
4
+ import { Surface } from "@dxos/app-framework/ui";
5
+ import { AppSurface } from "@dxos/app-toolkit/ui";
6
+ import * as Effect from "effect/Effect";
7
+ import { RangeList, SheetArticle } from "#containers";
8
+ //#region src/capabilities/react-surface.ts
9
+ var react_surface_default = Capability.makeModule(() => Effect.succeed(Capability.contributes(Capabilities.ReactSurface, [Surface.create({
10
+ id: "sheet",
11
+ filter: AppSurface.oneOf(AppSurface.object(AppSurface.Article, Sheet.Sheet, (data) => !!Obj.getDatabase(data.subject)), AppSurface.object(AppSurface.Section, Sheet.Sheet, (data) => !!Obj.getDatabase(data.subject))),
12
+ component: SheetArticle,
13
+ props: ({ role, data: { subject, attendableId } }) => ({
14
+ role,
15
+ subject,
16
+ attendableId
17
+ })
18
+ }), Surface.create({
19
+ id: "objectProperties",
20
+ filter: AppSurface.object(AppSurface.ObjectProperties, Sheet.Sheet),
21
+ component: RangeList,
22
+ props: ({ data: { subject } }) => ({ sheet: subject })
23
+ })])));
24
+ //#endregion
25
+ export { react_surface_default as default };
26
+
27
+ //# sourceMappingURL=chunk-react-surface.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-react-surface.mjs","names":[],"sources":["../../src/capabilities/react-surface.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capabilities, Capability } from '@dxos/app-framework';\nimport { Surface } from '@dxos/app-framework/ui';\nimport { AppSurface } from '@dxos/app-toolkit/ui';\nimport { Obj } from '@dxos/echo';\n\nimport { RangeList, SheetArticle } from '#containers';\nimport { Sheet } from '#types';\n\nexport default Capability.makeModule(() =>\n Effect.succeed(\n Capability.contributes(Capabilities.ReactSurface, [\n Surface.create({\n id: 'sheet',\n // TODO(wittjosiah): Split into multiple surfaces if this filter proves too strict for non-article roles.\n filter: AppSurface.oneOf(\n AppSurface.object(AppSurface.Article, Sheet.Sheet, (data) => !!Obj.getDatabase(data.subject)),\n AppSurface.object(AppSurface.Section, Sheet.Sheet, (data) => !!Obj.getDatabase(data.subject)),\n ),\n component: SheetArticle,\n props: ({ role, data: { subject, attendableId } }) => ({ role, subject, attendableId }),\n }),\n Surface.create({\n id: 'objectProperties',\n filter: AppSurface.object(AppSurface.ObjectProperties, Sheet.Sheet),\n component: RangeList,\n props: ({ data: { subject } }) => ({ sheet: subject }),\n }),\n ]),\n ),\n);\n"],"mappings":";;;;;;;;AAcA,IAAA,wBAAe,WAAW,iBACxB,OAAO,QACL,WAAW,YAAY,aAAa,cAAc,CAChD,QAAQ,OAAO;CACb,IAAI;CAEJ,QAAQ,WAAW,MACjB,WAAW,OAAO,WAAW,SAAS,MAAM,QAAQ,SAAS,CAAC,CAAC,IAAI,YAAY,KAAK,OAAO,CAAC,GAC5F,WAAW,OAAO,WAAW,SAAS,MAAM,QAAQ,SAAS,CAAC,CAAC,IAAI,YAAY,KAAK,OAAO,CAAC,CAC9F;CACA,WAAW;CACX,QAAQ,EAAE,MAAM,MAAM,EAAE,SAAS,sBAAsB;EAAE;EAAM;EAAS;CAAa;AACvF,CAAC,GACD,QAAQ,OAAO;CACb,IAAI;CACJ,QAAQ,WAAW,OAAO,WAAW,kBAAkB,MAAM,KAAK;CAClE,WAAW;CACX,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,OAAO,QAAQ;AACtD,CAAC,CACH,CAAC,CACH,CACF"}
@@ -0,0 +1,11 @@
1
+ import { a as RestoreAxis } from "./chunk-types.mjs";
2
+ import { Operation } from "@dxos/compute";
3
+ import * as Effect from "effect/Effect";
4
+ //#region src/operations/restore-axis.ts
5
+ var handler = RestoreAxis.pipe(Operation.withHandler(({ model, axis, ...restoreData }) => Effect.sync(() => {
6
+ model[axis === "col" ? "restoreColumn" : "restoreRow"](restoreData);
7
+ })));
8
+ //#endregion
9
+ export { handler as default };
10
+
11
+ //# sourceMappingURL=chunk-restore-axis.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-restore-axis.mjs","names":[],"sources":["../../src/operations/restore-axis.ts"],"sourcesContent":["//\n\nimport * as Effect from 'effect/Effect';\n// Copyright 2025 DXOS.org\n//\n\nimport { Operation } from '@dxos/compute';\n\nimport { SheetOperation } from '../types';\n\nconst handler: Operation.WithHandler<typeof SheetOperation.RestoreAxis> = SheetOperation.RestoreAxis.pipe(\n Operation.withHandler(({ model, axis, ...restoreData }) =>\n Effect.sync(() => {\n model[axis === 'col' ? 'restoreColumn' : 'restoreRow'](restoreData);\n }),\n ),\n);\n\nexport default handler;\n"],"mappings":";;;;AAUA,IAAM,UAAA,YAA+F,KACnG,UAAU,aAAa,EAAE,OAAO,MAAM,GAAG,kBACvC,OAAO,WAAW;CAChB,MAAM,SAAS,QAAQ,kBAAkB,aAAa,CAAC,WAAW;AACpE,CAAC,CACH,CACF"}
@@ -0,0 +1,20 @@
1
+ import { l as GridInstances, o as ScrollToAnchor } from "./chunk-types.mjs";
2
+ import { t as parseThreadAnchorAsCellRange } from "./chunk-thread-ranges.mjs";
3
+ import { Capability } from "@dxos/app-framework";
4
+ import { Operation } from "@dxos/compute";
5
+ import * as Effect from "effect/Effect";
6
+ //#region src/operations/scroll-to-anchor.ts
7
+ var handler = ScrollToAnchor.pipe(Operation.withHandler(Effect.fnUntraced(function* ({ subject, cursor, id }) {
8
+ const entry = (yield* Capability.get(GridInstances)).get(subject);
9
+ if (!entry) return;
10
+ entry.setActiveRefs(id);
11
+ const range = parseThreadAnchorAsCellRange(cursor);
12
+ if (range) entry.grid.setFocus({
13
+ ...range.to,
14
+ plane: "grid"
15
+ }, true);
16
+ })));
17
+ //#endregion
18
+ export { handler as default };
19
+
20
+ //# sourceMappingURL=chunk-scroll-to-anchor.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-scroll-to-anchor.mjs","names":[],"sources":["../../src/operations/scroll-to-anchor.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { Operation } from '@dxos/compute';\n\nimport { parseThreadAnchorAsCellRange } from '../integrations/thread-ranges';\nimport { SheetCapabilities, SheetOperation } from '../types';\n\nconst handler: Operation.WithHandler<typeof SheetOperation.ScrollToAnchor> = SheetOperation.ScrollToAnchor.pipe(\n Operation.withHandler(\n Effect.fnUntraced(function* ({ subject, cursor, id }) {\n const gridInstances = yield* Capability.get(SheetCapabilities.GridInstances);\n const entry = gridInstances.get(subject);\n if (!entry) {\n return;\n }\n\n entry.setActiveRefs(id);\n const range = parseThreadAnchorAsCellRange(cursor);\n if (range) {\n entry.grid.setFocus({ ...range.to, plane: 'grid' }, true);\n }\n }),\n ),\n);\n\nexport default handler;\n"],"mappings":";;;;;;AAYA,IAAM,UAAA,eAAqG,KACzG,UAAU,YACR,OAAO,WAAW,WAAW,EAAE,SAAS,QAAQ,MAAM;CAEpD,MAAM,SAAQ,OADe,WAAW,IAAI,aAA+B,EAAA,CAC/C,IAAI,OAAO;CACvC,IAAI,CAAC,OACH;CAGF,MAAM,cAAc,EAAE;CACtB,MAAM,QAAQ,6BAA6B,MAAM;CACjD,IAAI,OACF,MAAM,KAAK,SAAS;EAAE,GAAG,MAAM;EAAI,OAAO;CAAO,GAAG,IAAI;AAE5D,CAAC,CACH,CACF"}
@@ -0,0 +1,20 @@
1
+ import { S as addressToIndex, k as mapFormulaRefsToIndices, s as SetValues } from "./chunk-types.mjs";
2
+ import { Operation } from "@dxos/compute";
3
+ import { addressFromA1Notation, isFormula } from "@dxos/compute-hyperformula";
4
+ import { Database, Obj } from "@dxos/echo";
5
+ import * as Effect from "effect/Effect";
6
+ //#region src/operations/set-values.ts
7
+ var handler = SetValues.pipe(Operation.withHandler(Effect.fn(function* ({ sheet: sheetRef, cells }) {
8
+ const sheet = yield* Database.load(sheetRef);
9
+ Obj.update(sheet, (sheet) => {
10
+ for (const [address, value] of Object.entries(cells)) {
11
+ const idx = addressToIndex(sheet, addressFromA1Notation(address));
12
+ const stored = isFormula(String(value)) ? mapFormulaRefsToIndices(sheet, String(value)) : value;
13
+ sheet.cells[idx] = { value: stored };
14
+ }
15
+ });
16
+ })));
17
+ //#endregion
18
+ export { handler as default };
19
+
20
+ //# sourceMappingURL=chunk-set-values.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-set-values.mjs","names":[],"sources":["../../src/operations/set-values.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Operation } from '@dxos/compute';\nimport { addressFromA1Notation, isFormula } from '@dxos/compute-hyperformula';\nimport { Database, Obj } from '@dxos/echo';\n\nimport { SheetOperation, addressToIndex, mapFormulaRefsToIndices } from '../types';\n\nconst handler: Operation.WithHandler<typeof SheetOperation.SetValues> = SheetOperation.SetValues.pipe(\n Operation.withHandler(\n Effect.fn(function* ({ sheet: sheetRef, cells }) {\n const sheet = yield* Database.load(sheetRef);\n Obj.update(sheet, (sheet) => {\n for (const [address, value] of Object.entries(cells)) {\n const cell = addressFromA1Notation(address);\n const idx = addressToIndex(sheet, cell);\n const stored = isFormula(String(value)) ? mapFormulaRefsToIndices(sheet, String(value)) : value;\n sheet.cells[idx] = { value: stored };\n }\n });\n }),\n ),\n);\n\nexport default handler;\n"],"mappings":";;;;;;AAYA,IAAM,UAAA,UAA2F,KAC/F,UAAU,YACR,OAAO,GAAG,WAAW,EAAE,OAAO,UAAU,SAAS;CAC/C,MAAM,QAAQ,OAAO,SAAS,KAAK,QAAQ;CAC3C,IAAI,OAAO,QAAQ,UAAU;EAC3B,KAAK,MAAM,CAAC,SAAS,UAAU,OAAO,QAAQ,KAAK,GAAG;GAEpD,MAAM,MAAM,eAAe,OADd,sBAAsB,OACD,CAAI;GACtC,MAAM,SAAS,UAAU,OAAO,KAAK,CAAC,IAAI,wBAAwB,OAAO,OAAO,KAAK,CAAC,IAAI;GAC1F,MAAM,MAAM,OAAO,EAAE,OAAO,OAAO;EACrC;CACF,CAAC;AACH,CAAC,CACH,CACF"}
@@ -1,12 +1,10 @@
1
- import "./chunk-J5LGTIGS.mjs";
2
-
3
- // src/capabilities/skill-definition.ts
4
- import * as Effect from "effect/Effect";
5
1
  import { Capability } from "@dxos/app-framework";
6
2
  import { AppCapabilities } from "@dxos/app-toolkit";
3
+ import * as Effect from "effect/Effect";
7
4
  import { SheetSkill } from "#skills";
5
+ //#region src/capabilities/skill-definition.ts
8
6
  var skill_definition_default = Capability.makeModule(() => Effect.succeed(Capability.contributes(AppCapabilities.SkillDefinition, SheetSkill)));
9
- export {
10
- skill_definition_default as default
11
- };
12
- //# sourceMappingURL=skill-definition-U3KQCFOI.mjs.map
7
+ //#endregion
8
+ export { skill_definition_default as default };
9
+
10
+ //# sourceMappingURL=chunk-skill-definition.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-skill-definition.mjs","names":[],"sources":["../../src/capabilities/skill-definition.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { AppCapabilities } from '@dxos/app-toolkit';\n\nimport { SheetSkill } from '#skills';\n\nexport default Capability.makeModule(() =>\n Effect.succeed(Capability.contributes(AppCapabilities.SkillDefinition, SheetSkill)),\n);\n"],"mappings":";;;;;AAWA,IAAA,2BAAe,WAAW,iBACxB,OAAO,QAAQ,WAAW,YAAY,gBAAgB,iBAAiB,UAAU,CAAC,CACpF"}