@dxos/plugin-sheet 0.6.12-main.f9d0246 → 0.6.12-staging.0b4bb48

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 (263) hide show
  1. package/dist/lib/browser/{chunk-ZLJ2GRE2.mjs → SheetContainer-U4H5D34A.mjs} +240 -1151
  2. package/dist/lib/browser/SheetContainer-U4H5D34A.mjs.map +7 -0
  3. package/dist/lib/browser/chunk-APHOLYUB.mjs +175 -0
  4. package/dist/lib/browser/chunk-APHOLYUB.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-Z2XOOC2R.mjs → chunk-D5AGLXJP.mjs} +678 -385
  6. package/dist/lib/browser/chunk-D5AGLXJP.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-WZMOZKQZ.mjs → chunk-FUAGSXA4.mjs} +16 -9
  8. package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +7 -0
  9. package/dist/lib/{node-esm/chunk-IU2L277A.mjs → browser/chunk-JRL5LGCE.mjs} +5 -4
  10. package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-NU4PBN33.mjs +8 -0
  12. package/dist/lib/browser/chunk-NU4PBN33.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +60 -74
  14. package/dist/lib/browser/index.mjs.map +3 -3
  15. package/dist/lib/browser/meta.json +1 -1
  16. package/dist/lib/browser/meta.mjs +1 -1
  17. package/dist/lib/browser/testing.mjs +92 -0
  18. package/dist/lib/browser/testing.mjs.map +7 -0
  19. package/dist/lib/browser/types.mjs +6 -4
  20. package/dist/lib/node/{chunk-6DQABRGJ.cjs → SheetContainer-AXQV3ZT5.cjs} +279 -1182
  21. package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs.map +7 -0
  22. package/dist/lib/node/{chunk-P5QYYEHQ.cjs → chunk-5KKJ4NPP.cjs} +676 -388
  23. package/dist/lib/node/chunk-5KKJ4NPP.cjs.map +7 -0
  24. package/dist/lib/node/{chunk-BNARJ5GM.cjs → chunk-BJ6ZD7MN.cjs} +18 -5
  25. package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +7 -0
  26. package/dist/lib/node/chunk-CN3RPESU.cjs +202 -0
  27. package/dist/lib/node/chunk-CN3RPESU.cjs.map +7 -0
  28. package/dist/lib/node/{chunk-AOP42UAA.cjs → chunk-DSYKOI4E.cjs} +21 -13
  29. package/dist/lib/node/chunk-DSYKOI4E.cjs.map +7 -0
  30. package/dist/lib/node/chunk-PYXHNAAK.cjs +40 -0
  31. package/dist/lib/node/chunk-PYXHNAAK.cjs.map +7 -0
  32. package/dist/lib/node/index.cjs +66 -86
  33. package/dist/lib/node/index.cjs.map +3 -3
  34. package/dist/lib/node/meta.cjs +3 -3
  35. package/dist/lib/node/meta.cjs.map +1 -1
  36. package/dist/lib/node/meta.json +1 -1
  37. package/dist/lib/node/testing.cjs +111 -0
  38. package/dist/lib/node/testing.cjs.map +7 -0
  39. package/dist/lib/node/types.cjs +12 -10
  40. package/dist/lib/node/types.cjs.map +2 -2
  41. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  42. package/dist/types/src/components/CellEditor/CellEditor.d.ts +3 -23
  43. package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +1 -1
  44. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts +2 -2
  45. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +1 -1
  46. package/dist/types/src/components/CellEditor/extension.d.ts +1 -1
  47. package/dist/types/src/components/CellEditor/extension.d.ts.map +1 -1
  48. package/dist/types/src/{graph → components/ComputeGraph}/async-function.d.ts +2 -8
  49. package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +1 -0
  50. package/dist/types/src/{graph/testing/custom-function.d.ts → components/ComputeGraph/custom.d.ts} +2 -4
  51. package/dist/types/src/components/ComputeGraph/custom.d.ts.map +1 -0
  52. package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +1 -0
  53. package/dist/types/src/components/ComputeGraph/graph-context.d.ts +12 -0
  54. package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +1 -0
  55. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +2 -0
  56. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +1 -0
  57. package/dist/types/src/components/ComputeGraph/graph.d.ts +26 -0
  58. package/dist/types/src/components/ComputeGraph/graph.d.ts.map +1 -0
  59. package/dist/types/src/components/ComputeGraph/index.d.ts +3 -1
  60. package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
  61. package/dist/types/src/components/Sheet/Sheet.d.ts +1 -1
  62. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
  63. package/dist/types/src/components/Sheet/Sheet.stories.d.ts +6 -5
  64. package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -1
  65. package/dist/types/src/components/Sheet/formatting.d.ts +14 -0
  66. package/dist/types/src/components/Sheet/formatting.d.ts.map +1 -0
  67. package/dist/types/src/components/Sheet/grid.d.ts +2 -2
  68. package/dist/types/src/components/Sheet/grid.d.ts.map +1 -1
  69. package/dist/types/src/components/Sheet/nav.d.ts +3 -3
  70. package/dist/types/src/components/Sheet/nav.d.ts.map +1 -1
  71. package/dist/types/src/components/Sheet/sheet-context.d.ts +7 -8
  72. package/dist/types/src/components/Sheet/sheet-context.d.ts.map +1 -1
  73. package/dist/types/src/components/SheetContainer.d.ts +3 -2
  74. package/dist/types/src/components/SheetContainer.d.ts.map +1 -1
  75. package/dist/types/src/components/Toolbar/Toolbar.d.ts +3 -19
  76. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  77. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +13 -18
  78. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  79. package/dist/types/src/components/index.d.ts +2 -2
  80. package/dist/types/src/components/index.d.ts.map +1 -1
  81. package/dist/types/src/meta.d.ts +4 -1
  82. package/dist/types/src/meta.d.ts.map +1 -1
  83. package/dist/types/src/{graph/function-defs.d.ts → model/functions.d.ts} +1 -1
  84. package/dist/types/src/model/functions.d.ts.map +1 -0
  85. package/dist/types/src/model/index.d.ts +3 -2
  86. package/dist/types/src/model/index.d.ts.map +1 -1
  87. package/dist/types/src/model/model.browser.test.d.ts +2 -0
  88. package/dist/types/src/model/model.browser.test.d.ts.map +1 -0
  89. package/dist/types/src/model/{sheet-model.d.ts → model.d.ts} +65 -10
  90. package/dist/types/src/model/model.d.ts.map +1 -0
  91. package/dist/types/src/{defs → model}/types.d.ts +3 -8
  92. package/dist/types/src/model/types.d.ts.map +1 -0
  93. package/dist/types/src/model/types.test.d.ts.map +1 -0
  94. package/dist/types/src/model/util.d.ts +15 -0
  95. package/dist/types/src/model/util.d.ts.map +1 -0
  96. package/dist/types/src/testing.d.ts +9 -0
  97. package/dist/types/src/testing.d.ts.map +1 -0
  98. package/dist/types/src/translations.d.ts +12 -17
  99. package/dist/types/src/translations.d.ts.map +1 -1
  100. package/dist/types/src/types.d.ts +5 -86
  101. package/dist/types/src/types.d.ts.map +1 -1
  102. package/package.json +41 -48
  103. package/src/SheetPlugin.tsx +73 -48
  104. package/src/components/CellEditor/CellEditor.stories.tsx +4 -5
  105. package/src/components/CellEditor/CellEditor.tsx +9 -59
  106. package/src/components/CellEditor/extension.test.ts +5 -4
  107. package/src/components/CellEditor/extension.ts +3 -1
  108. package/src/{graph → components/ComputeGraph}/async-function.ts +6 -15
  109. package/src/{graph/testing/custom-function.ts → components/ComputeGraph/custom.ts} +7 -11
  110. package/src/{graph → components/ComputeGraph}/edge-function.ts +3 -3
  111. package/src/components/ComputeGraph/graph-context.tsx +50 -0
  112. package/src/components/ComputeGraph/graph.browser.test.ts +50 -0
  113. package/src/components/ComputeGraph/graph.ts +62 -0
  114. package/src/components/ComputeGraph/index.ts +3 -1
  115. package/src/components/Sheet/Sheet.stories.tsx +88 -52
  116. package/src/components/Sheet/Sheet.tsx +18 -57
  117. package/src/{model/formatting-model.ts → components/Sheet/formatting.ts} +13 -20
  118. package/src/components/Sheet/grid.ts +3 -3
  119. package/src/components/Sheet/nav.ts +19 -19
  120. package/src/components/Sheet/sheet-context.tsx +80 -18
  121. package/src/components/SheetContainer.tsx +19 -73
  122. package/src/components/Toolbar/Toolbar.tsx +12 -53
  123. package/src/components/index.ts +0 -1
  124. package/src/meta.tsx +5 -1
  125. package/src/model/index.ts +3 -2
  126. package/src/model/model.browser.test.ts +100 -0
  127. package/src/model/model.ts +550 -0
  128. package/src/{defs → model}/types.test.ts +9 -8
  129. package/src/{defs → model}/types.ts +14 -24
  130. package/src/model/util.ts +36 -0
  131. package/src/testing.ts +50 -0
  132. package/src/translations.ts +1 -6
  133. package/src/types.ts +6 -31
  134. package/dist/lib/browser/SheetContainer-VISF3VUB.mjs +0 -261
  135. package/dist/lib/browser/SheetContainer-VISF3VUB.mjs.map +0 -7
  136. package/dist/lib/browser/chunk-QILRZNE5.mjs +0 -15
  137. package/dist/lib/browser/chunk-QILRZNE5.mjs.map +0 -7
  138. package/dist/lib/browser/chunk-WZMOZKQZ.mjs.map +0 -7
  139. package/dist/lib/browser/chunk-Z2XOOC2R.mjs.map +0 -7
  140. package/dist/lib/browser/chunk-ZLJ2GRE2.mjs.map +0 -7
  141. package/dist/lib/browser/graph-4XFKIHRL.mjs +0 -21
  142. package/dist/lib/browser/graph-4XFKIHRL.mjs.map +0 -7
  143. package/dist/lib/node/SheetContainer-2MEALQWW.cjs +0 -279
  144. package/dist/lib/node/SheetContainer-2MEALQWW.cjs.map +0 -7
  145. package/dist/lib/node/chunk-6DQABRGJ.cjs.map +0 -7
  146. package/dist/lib/node/chunk-AOP42UAA.cjs.map +0 -7
  147. package/dist/lib/node/chunk-BNARJ5GM.cjs.map +0 -7
  148. package/dist/lib/node/chunk-P5QYYEHQ.cjs.map +0 -7
  149. package/dist/lib/node/graph-2LRDUXBZ.cjs +0 -43
  150. package/dist/lib/node/graph-2LRDUXBZ.cjs.map +0 -7
  151. package/dist/lib/node-esm/SheetContainer-RPSUSXWS.mjs +0 -262
  152. package/dist/lib/node-esm/SheetContainer-RPSUSXWS.mjs.map +0 -7
  153. package/dist/lib/node-esm/chunk-4MM7THJW.mjs +0 -2944
  154. package/dist/lib/node-esm/chunk-4MM7THJW.mjs.map +0 -7
  155. package/dist/lib/node-esm/chunk-5RLTCIE2.mjs +0 -2684
  156. package/dist/lib/node-esm/chunk-5RLTCIE2.mjs.map +0 -7
  157. package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +0 -7
  158. package/dist/lib/node-esm/chunk-RR2AO4SM.mjs +0 -76
  159. package/dist/lib/node-esm/chunk-RR2AO4SM.mjs.map +0 -7
  160. package/dist/lib/node-esm/graph-WG5EKOMO.mjs +0 -22
  161. package/dist/lib/node-esm/graph-WG5EKOMO.mjs.map +0 -7
  162. package/dist/lib/node-esm/index.mjs +0 -263
  163. package/dist/lib/node-esm/index.mjs.map +0 -7
  164. package/dist/lib/node-esm/meta.json +0 -1
  165. package/dist/lib/node-esm/meta.mjs +0 -10
  166. package/dist/lib/node-esm/meta.mjs.map +0 -7
  167. package/dist/lib/node-esm/types.mjs +0 -21
  168. package/dist/lib/node-esm/types.mjs.map +0 -7
  169. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +0 -11
  170. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +0 -1
  171. package/dist/types/src/components/GridSheet/GridSheet.d.ts +0 -10
  172. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +0 -1
  173. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +0 -9
  174. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +0 -1
  175. package/dist/types/src/components/GridSheet/util.d.ts +0 -7
  176. package/dist/types/src/components/GridSheet/util.d.ts.map +0 -1
  177. package/dist/types/src/components/Sheet/decorations.d.ts +0 -24
  178. package/dist/types/src/components/Sheet/decorations.d.ts.map +0 -1
  179. package/dist/types/src/components/Sheet/threads.d.ts +0 -2
  180. package/dist/types/src/components/Sheet/threads.d.ts.map +0 -1
  181. package/dist/types/src/defs/index.d.ts +0 -3
  182. package/dist/types/src/defs/index.d.ts.map +0 -1
  183. package/dist/types/src/defs/types.d.ts.map +0 -1
  184. package/dist/types/src/defs/types.test.d.ts.map +0 -1
  185. package/dist/types/src/defs/util.d.ts +0 -43
  186. package/dist/types/src/defs/util.d.ts.map +0 -1
  187. package/dist/types/src/extensions/compute.d.ts +0 -9
  188. package/dist/types/src/extensions/compute.d.ts.map +0 -1
  189. package/dist/types/src/extensions/compute.stories.d.ts +0 -26
  190. package/dist/types/src/extensions/compute.stories.d.ts.map +0 -1
  191. package/dist/types/src/extensions/index.d.ts +0 -2
  192. package/dist/types/src/extensions/index.d.ts.map +0 -1
  193. package/dist/types/src/graph/async-function.d.ts.map +0 -1
  194. package/dist/types/src/graph/compute-graph.d.ts +0 -84
  195. package/dist/types/src/graph/compute-graph.d.ts.map +0 -1
  196. package/dist/types/src/graph/compute-graph.stories.d.ts +0 -10
  197. package/dist/types/src/graph/compute-graph.stories.d.ts.map +0 -1
  198. package/dist/types/src/graph/compute-graph.test.d.ts +0 -2
  199. package/dist/types/src/graph/compute-graph.test.d.ts.map +0 -1
  200. package/dist/types/src/graph/compute-node.d.ts +0 -26
  201. package/dist/types/src/graph/compute-node.d.ts.map +0 -1
  202. package/dist/types/src/graph/edge-function.d.ts.map +0 -1
  203. package/dist/types/src/graph/function-defs.d.ts.map +0 -1
  204. package/dist/types/src/graph/hyperformula.test.d.ts +0 -2
  205. package/dist/types/src/graph/hyperformula.test.d.ts.map +0 -1
  206. package/dist/types/src/graph/index.d.ts +0 -4
  207. package/dist/types/src/graph/index.d.ts.map +0 -1
  208. package/dist/types/src/graph/testing/custom-function.d.ts.map +0 -1
  209. package/dist/types/src/graph/testing/index.d.ts +0 -2
  210. package/dist/types/src/graph/testing/index.d.ts.map +0 -1
  211. package/dist/types/src/graph/util.d.ts +0 -2
  212. package/dist/types/src/graph/util.d.ts.map +0 -1
  213. package/dist/types/src/hooks/hooks.stories.d.ts +0 -11
  214. package/dist/types/src/hooks/hooks.stories.d.ts.map +0 -1
  215. package/dist/types/src/hooks/index.d.ts +0 -4
  216. package/dist/types/src/hooks/index.d.ts.map +0 -1
  217. package/dist/types/src/hooks/useComputeGraph.d.ts +0 -7
  218. package/dist/types/src/hooks/useComputeGraph.d.ts.map +0 -1
  219. package/dist/types/src/hooks/useFormattingModel.d.ts +0 -3
  220. package/dist/types/src/hooks/useFormattingModel.d.ts.map +0 -1
  221. package/dist/types/src/hooks/useSheetModel.d.ts +0 -8
  222. package/dist/types/src/hooks/useSheetModel.d.ts.map +0 -1
  223. package/dist/types/src/model/formatting-model.d.ts +0 -16
  224. package/dist/types/src/model/formatting-model.d.ts.map +0 -1
  225. package/dist/types/src/model/sheet-model.d.ts.map +0 -1
  226. package/dist/types/src/sanity.test.d.ts +0 -2
  227. package/dist/types/src/sanity.test.d.ts.map +0 -1
  228. package/dist/types/src/testing/index.d.ts +0 -2
  229. package/dist/types/src/testing/index.d.ts.map +0 -1
  230. package/dist/types/src/testing/testing.d.ts +0 -8
  231. package/dist/types/src/testing/testing.d.ts.map +0 -1
  232. package/dist/vendor/hyperformula.mjs +0 -37145
  233. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +0 -20
  234. package/src/components/GridSheet/GridSheet.stories.tsx +0 -36
  235. package/src/components/GridSheet/GridSheet.tsx +0 -153
  236. package/src/components/GridSheet/util.ts +0 -108
  237. package/src/components/Sheet/decorations.ts +0 -62
  238. package/src/components/Sheet/threads.tsx +0 -205
  239. package/src/defs/index.ts +0 -6
  240. package/src/defs/util.ts +0 -151
  241. package/src/extensions/compute.stories.tsx +0 -153
  242. package/src/extensions/compute.ts +0 -131
  243. package/src/extensions/index.ts +0 -5
  244. package/src/graph/compute-graph.stories.tsx +0 -93
  245. package/src/graph/compute-graph.test.ts +0 -127
  246. package/src/graph/compute-graph.ts +0 -313
  247. package/src/graph/compute-node.ts +0 -62
  248. package/src/graph/hyperformula.test.ts +0 -15
  249. package/src/graph/index.ts +0 -7
  250. package/src/graph/testing/index.ts +0 -5
  251. package/src/graph/util.ts +0 -8
  252. package/src/hooks/hooks.stories.tsx +0 -50
  253. package/src/hooks/index.ts +0 -7
  254. package/src/hooks/useComputeGraph.ts +0 -21
  255. package/src/hooks/useFormattingModel.ts +0 -11
  256. package/src/hooks/useSheetModel.ts +0 -40
  257. package/src/model/sheet-model.ts +0 -414
  258. package/src/sanity.test.ts +0 -40
  259. package/src/testing/index.ts +0 -5
  260. package/src/testing/testing.tsx +0 -68
  261. /package/dist/types/src/{graph → components/ComputeGraph}/edge-function.d.ts +0 -0
  262. /package/dist/types/src/{defs → model}/types.test.d.ts +0 -0
  263. /package/src/{graph/function-defs.ts → model/functions.ts} +0 -0
package/src/defs/util.ts DELETED
@@ -1,151 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { randomBytes } from '@dxos/crypto';
6
- import { create } from '@dxos/echo-schema';
7
-
8
- import {
9
- addressFromA1Notation,
10
- type CellAddress,
11
- type CellRange,
12
- DEFAULT_COLUMNS,
13
- DEFAULT_ROWS,
14
- MAX_COLUMNS,
15
- MAX_ROWS,
16
- } from './types';
17
- import { type CreateSheetOptions, type SheetSize, SheetType } from '../types';
18
-
19
- // TODO(burdon): Factor out from dxos/protocols to new common package.
20
- export class ApiError extends Error {}
21
-
22
- export class ReadonlyException extends ApiError {}
23
-
24
- export class RangeException extends ApiError {
25
- constructor(n: number) {
26
- super();
27
- }
28
- }
29
-
30
- /**
31
- * With a string length of 8, the chance of a collision is 0.02% for a sheet with 10,000 strings.
32
- */
33
- export const createIndex = (length = 8): string => {
34
- const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
35
- const charactersLength = characters.length;
36
- const randomBuffer = randomBytes(length);
37
- return Array.from(randomBuffer, (byte) => characters[byte % charactersLength]).join('');
38
- };
39
-
40
- export const createIndices = (length: number): string[] => Array.from({ length }).map(() => createIndex());
41
-
42
- export const insertIndices = (indices: string[], i: number, n: number, max: number) => {
43
- if (i + n > max) {
44
- throw new RangeException(i + n);
45
- }
46
-
47
- const idx = createIndices(n);
48
- indices.splice(i, 0, ...idx);
49
- };
50
-
51
- export const initialize = (
52
- sheet: SheetType,
53
- { rows = DEFAULT_ROWS, columns = DEFAULT_COLUMNS }: Partial<SheetSize> = {},
54
- ) => {
55
- if (!sheet.rows.length) {
56
- insertIndices(sheet.rows, 0, rows, MAX_ROWS);
57
- }
58
- if (!sheet.columns.length) {
59
- insertIndices(sheet.columns, 0, columns, MAX_COLUMNS);
60
- }
61
- };
62
-
63
- export const createSheet = ({ name, cells, ...size }: CreateSheetOptions = {}): SheetType => {
64
- const sheet = create(SheetType, {
65
- name,
66
- cells: {},
67
- rows: [],
68
- columns: [],
69
- rowMeta: {},
70
- columnMeta: {},
71
- formatting: {},
72
- });
73
-
74
- initialize(sheet, size);
75
-
76
- if (cells) {
77
- Object.entries(cells).forEach(([key, { value }]) => {
78
- const idx = addressToIndex(sheet, addressFromA1Notation(key));
79
- sheet.cells[idx] = { value };
80
- });
81
- }
82
-
83
- return sheet;
84
- };
85
-
86
- /**
87
- * E.g., "A1" => "CA2@CB3".
88
- */
89
- export const addressToIndex = (sheet: SheetType, cell: CellAddress): string => {
90
- return `${sheet.columns[cell.col]}@${sheet.rows[cell.row]}`;
91
- };
92
-
93
- /**
94
- * E.g., "CA2@CB3" => "A1".
95
- */
96
- export const addressFromIndex = (sheet: SheetType, idx: string): CellAddress => {
97
- const [column, row] = idx.split('@');
98
- return {
99
- col: sheet.columns.indexOf(column),
100
- row: sheet.rows.indexOf(row),
101
- };
102
- };
103
-
104
- /**
105
- * E.g., "A1:B2" => "CA2@CB3:CC4@CD5".
106
- */
107
- export const rangeToIndex = (sheet: SheetType, range: CellRange): string => {
108
- return [range.from, range.to ?? range.from].map((cell) => addressToIndex(sheet, cell)).join(':');
109
- };
110
-
111
- /**
112
- * E.g., "CA2@CB3:CC4@CD5" => "A1:B2".
113
- */
114
- export const rangeFromIndex = (sheet: SheetType, idx: string): CellRange => {
115
- const [from, to] = idx.split(':').map((index) => addressFromIndex(sheet, index));
116
- return { from, to };
117
- };
118
-
119
- /**
120
- * Find closest cell to cursor.
121
- */
122
- export const closest = (cursor: CellAddress, cells: CellAddress[]): CellAddress | undefined => {
123
- let closestCell: CellAddress | undefined;
124
- let closestDistance = Number.MAX_SAFE_INTEGER;
125
-
126
- for (const cell of cells) {
127
- const distance = Math.abs(cell.row - cursor.row) + Math.abs(cell.col - cursor.col);
128
- if (distance < closestDistance) {
129
- closestCell = cell;
130
- closestDistance = distance;
131
- }
132
- }
133
-
134
- return closestCell;
135
- };
136
-
137
- /**
138
- * Compares the positions of two cell indexes in a sheet.
139
- * Sorts primarily by row, then by column if rows are equal.
140
- */
141
- export const compareIndexPositions = (sheet: SheetType, indexA: string, indexB: string): number => {
142
- const { row: rowA, col: columnA } = addressFromIndex(sheet, indexA);
143
- const { row: rowB, col: columnB } = addressFromIndex(sheet, indexB);
144
-
145
- // Sort by row first, then by column.
146
- if (rowA !== rowB) {
147
- return rowA - rowB;
148
- } else {
149
- return columnA - columnB;
150
- }
151
- };
@@ -1,153 +0,0 @@
1
- //
2
- // Copyright 2023 DXOS.org
3
- //
4
-
5
- import '@dxos-theme';
6
- import React, { useEffect } from 'react';
7
-
8
- import { useSpace } from '@dxos/react-client/echo';
9
- import { withClientProvider } from '@dxos/react-client/testing';
10
- import { useAsyncState } from '@dxos/react-hooks';
11
- import { useThemeContext } from '@dxos/react-ui';
12
- import {
13
- createBasicExtensions,
14
- createMarkdownExtensions,
15
- createThemeExtensions,
16
- decorateMarkdown,
17
- useTextEditor,
18
- } from '@dxos/react-ui-editor';
19
- import { withTheme, withLayout } from '@dxos/storybook-utils';
20
- import { nonNullable } from '@dxos/util';
21
-
22
- import { compute, computeNodeFacet } from './compute';
23
- import { Sheet } from '../components';
24
- import { type ComputeNode } from '../graph';
25
- import { useComputeGraph, useSheetModel } from '../hooks';
26
- import { useTestSheet, withComputeGraphDecorator } from '../testing';
27
- import { SheetType } from '../types';
28
-
29
- const str = (...lines: string[]) => lines.join('\n');
30
-
31
- type EditorProps = {
32
- text?: string;
33
- };
34
-
35
- // TODO(burdon): Implement named expressions.
36
- // https://hyperformula.handsontable.com/guide/cell-references.html
37
-
38
- // TODO(burdon): Inline Adobe eCharts.
39
-
40
- const DOC_NAME = 'Test Doc';
41
- const SHEET_NAME = 'Test Sheet';
42
-
43
- const Editor = ({ text }: EditorProps) => {
44
- const { themeMode } = useThemeContext();
45
- const space = useSpace();
46
- const graph = useComputeGraph(space);
47
- const [computeNode] = useAsyncState<ComputeNode>(async () => {
48
- return graph ? await graph.getOrCreateNode(DOC_NAME) : undefined;
49
- }, [graph]);
50
- const { parentRef, focusAttributes } = useTextEditor(
51
- () => ({
52
- initialValue: text,
53
- extensions: [
54
- createBasicExtensions(),
55
- createMarkdownExtensions({ themeMode }),
56
- createThemeExtensions({ themeMode, syntaxHighlighting: true }),
57
- computeNode && computeNodeFacet.of(computeNode),
58
- compute(),
59
- decorateMarkdown(),
60
- ].filter(nonNullable),
61
- }),
62
- [computeNode, themeMode],
63
- );
64
-
65
- return <div className='w-[40rem] overflow-hidden' ref={parentRef} {...focusAttributes} />;
66
- };
67
-
68
- const Grid = () => {
69
- const space = useSpace();
70
- const graph = useComputeGraph(space);
71
- const sheet = useTestSheet(space, graph, { name: SHEET_NAME });
72
- const model = useSheetModel(graph, sheet);
73
- useEffect(() => {
74
- if (model) {
75
- model.setValues({ A1: { value: 100 }, A2: { value: 200 }, A3: { value: 300 }, A5: { value: '=SUM(A1:A3)' } });
76
- }
77
- }, [model]);
78
-
79
- if (!graph || !sheet) {
80
- return null;
81
- }
82
-
83
- return (
84
- <div className='flex w-[40rem] overflow-hidden'>
85
- <Sheet.Root graph={graph} sheet={sheet}>
86
- <Sheet.Main classNames='border border-separator' />
87
- </Sheet.Root>
88
- </div>
89
- );
90
- };
91
-
92
- const Story = (props: EditorProps) => {
93
- return (
94
- <div className='grid grid-rows-2'>
95
- <Editor {...props} />
96
- <Grid />
97
- </div>
98
- );
99
- };
100
-
101
- export default {
102
- title: 'plugin-sheet/extensions',
103
- decorators: [
104
- withClientProvider({ types: [SheetType], createIdentity: true, createSpace: true }),
105
- withComputeGraphDecorator(),
106
- withTheme,
107
- withLayout({ fullscreen: true, classNames: 'justify-center' }),
108
- ],
109
- parameters: { layout: 'fullscreen' },
110
- };
111
-
112
- // TODO(burdon): Inline formulae.
113
- export const Default = {
114
- render: Editor,
115
- args: {
116
- text: str(
117
- //
118
- '# Compute Graph',
119
- '',
120
- 'This is a compute expression:',
121
- '',
122
- '```dx',
123
- '=SUM(1, 2)',
124
- '```',
125
- '',
126
- 'It should change in realtime.',
127
- '',
128
- '```dx',
129
- '=SUM(3, 5)',
130
- '```',
131
- '',
132
- '',
133
- ),
134
- },
135
- };
136
-
137
- export const Graph = {
138
- render: Story,
139
- args: {
140
- text: str(
141
- //
142
- '# Compute Graph',
143
- '',
144
- 'The total projected cost is:',
145
- '',
146
- '```dx',
147
- `="${SHEET_NAME}"!A5`,
148
- '```',
149
- '',
150
- '',
151
- ),
152
- },
153
- };
@@ -1,131 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { syntaxTree } from '@codemirror/language';
6
- import { Facet } from '@codemirror/state';
7
- import {
8
- type EditorState,
9
- type Extension,
10
- type RangeSet,
11
- RangeSetBuilder,
12
- StateEffect,
13
- StateField,
14
- type Transaction,
15
- } from '@codemirror/state';
16
- import { Decoration, EditorView, ViewPlugin, WidgetType } from '@codemirror/view';
17
-
18
- import { type UnsubscribeCallback } from '@dxos/async';
19
- import { type Space } from '@dxos/client/echo';
20
-
21
- import { type CellAddress } from '../defs';
22
- import { type ComputeNode } from '../graph';
23
- import { type CellScalarValue } from '../types';
24
-
25
- export const spaceFacet = Facet.define<Space, Space>({
26
- combine: (values) => values[0],
27
- });
28
-
29
- // TODO(burdon): Create on demand?
30
- export const computeNodeFacet = Facet.define<ComputeNode, ComputeNode>({
31
- combine: (values) => values[0],
32
- });
33
-
34
- const LANGUAGE_TAG = 'dx';
35
-
36
- // TODO(burdon): Create marker just for our decorator?
37
- const updateAllDecorations = StateEffect.define<void>();
38
-
39
- export type ComputeOptions = {};
40
-
41
- export const compute = (options: ComputeOptions = {}): Extension => {
42
- const update = (state: EditorState, rangeSet?: RangeSet<Decoration>) => {
43
- const builder = new RangeSetBuilder<Decoration>();
44
- const computeNode = state.facet(computeNodeFacet);
45
- if (computeNode) {
46
- computeNode.clear();
47
- syntaxTree(state).iterate({
48
- enter: (node) => {
49
- if (node.name === 'FencedCode') {
50
- const cursor = state.selection.main.head;
51
- if (state.readOnly || cursor < node.from || cursor > node.to) {
52
- const info = node.node.getChild('CodeInfo');
53
- if (info) {
54
- const type = state.sliceDoc(info.from, info.to);
55
- const text = node.node.getChild('CodeText');
56
- if (type === LANGUAGE_TAG && text) {
57
- const formula = state.sliceDoc(text.from, text.to);
58
- const iter = rangeSet?.iter(node.node.from);
59
- if (iter?.value && iter?.value.spec.formula === formula) {
60
- builder.add(node.from, node.to, iter.value);
61
- } else {
62
- const cell: CellAddress = { col: node.node.from, row: 0 };
63
- computeNode.setValue(cell, formula);
64
- const value = computeNode.getValue(cell);
65
- builder.add(
66
- node.from,
67
- node.to,
68
- Decoration.replace({
69
- widget: new DxWidget(formula, value),
70
- formula,
71
- }),
72
- );
73
- }
74
- }
75
- }
76
- }
77
- }
78
- },
79
- });
80
- }
81
-
82
- return builder.finish();
83
- };
84
-
85
- return [
86
- // Graph subscription.
87
- ViewPlugin.fromClass(
88
- class {
89
- private readonly _subscription?: UnsubscribeCallback;
90
- constructor(view: EditorView) {
91
- const computeNode = view.state.facet(computeNodeFacet);
92
- if (computeNode) {
93
- this._subscription = computeNode.update.on(({ type }) => {
94
- if (type === 'valuesUpdated') {
95
- view.dispatch({
96
- effects: updateAllDecorations.of(),
97
- });
98
- }
99
- });
100
- }
101
- }
102
-
103
- destroy() {
104
- this._subscription?.();
105
- }
106
- },
107
- ),
108
-
109
- StateField.define<RangeSet<Decoration>>({
110
- create: (state) => update(state),
111
- update: (rangeSet: RangeSet<Decoration>, tr: Transaction) => update(tr.state, rangeSet),
112
- provide: (field) => EditorView.decorations.from(field),
113
- }),
114
- ];
115
- };
116
-
117
- class DxWidget extends WidgetType {
118
- constructor(
119
- private readonly formula: string,
120
- private readonly value: CellScalarValue,
121
- ) {
122
- super();
123
- }
124
-
125
- override toDOM(_view: EditorView) {
126
- const div = document.createElement('div');
127
- div.setAttribute('title', this.formula);
128
- div.innerText = String(this.value);
129
- return div;
130
- }
131
- }
@@ -1,5 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- export * from './compute';
@@ -1,93 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import '@dxos-theme';
6
-
7
- import React, { useEffect, useRef, useState } from 'react';
8
-
9
- import { FunctionType } from '@dxos/plugin-script/types';
10
- import { create, useSpace, Filter } from '@dxos/react-client/echo';
11
- import { withClientProvider } from '@dxos/react-client/testing';
12
- import { Toolbar, Button, Input } from '@dxos/react-ui';
13
- import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
14
- import { withTheme } from '@dxos/storybook-utils';
15
-
16
- import { testPlugins } from './testing';
17
- import { createSheet } from '../defs';
18
- import { useComputeGraph, useSheetModel } from '../hooks';
19
- import { withComputeGraphDecorator } from '../testing';
20
- import { SheetType } from '../types';
21
-
22
- const FUNCTION_NAME = 'TEST';
23
-
24
- const Story = () => {
25
- const space = useSpace();
26
- const graph = useComputeGraph(space);
27
- const [sheet, setSheet] = useState<SheetType>();
28
- const [text, setText] = useState(`${FUNCTION_NAME}(100)`);
29
- const [result, setResult] = useState<any>();
30
- const model = useSheetModel(graph, sheet);
31
- useEffect(() => {
32
- if (space) {
33
- const sheet = space.db.add(createSheet());
34
- setSheet(sheet);
35
- }
36
- }, [space]);
37
-
38
- useEffect(() => {
39
- if (space && graph) {
40
- graph.update.on(() => {
41
- const f1 = graph.getFunctions({ standard: true, echo: false });
42
- const f2 = graph.getFunctions({ standard: false, echo: true });
43
- setResult({ functions: { standard: f1.length, echo: f2.length } });
44
- });
45
-
46
- space.db.add(create(FunctionType, { version: 1, binding: FUNCTION_NAME }));
47
- }
48
- }, [space, graph]);
49
-
50
- const inputRef = useRef<HTMLInputElement | null>(null);
51
- const handleTest = async () => {
52
- if (space && graph) {
53
- const { objects } = await space.db.query(Filter.schema(FunctionType)).run();
54
- const mapped = graph.mapFunctionBindingToId(text);
55
- const unmapped = graph.mapFunctionBindingFromId(mapped);
56
- const internal = graph.mapFormulaToNative(text);
57
- setResult({ mapped, unmapped, internal, functions: objects.map((object) => object.id) });
58
- }
59
-
60
- inputRef.current?.focus();
61
- };
62
-
63
- return (
64
- <div className='flex flex-col gap-2 '>
65
- <Toolbar.Root>
66
- <Input.Root>
67
- <Input.TextInput
68
- ref={inputRef}
69
- placeholder='Formula'
70
- value={text}
71
- onChange={(ev) => setText(ev.target.value)}
72
- />
73
- </Input.Root>
74
- <Button onClick={handleTest}>Test</Button>
75
- </Toolbar.Root>
76
- <SyntaxHighlighter language='json'>
77
- {JSON.stringify({ space: space?.id, graph: graph?.id, sheet: sheet?.id, model: model?.id, result }, null, 2)}
78
- </SyntaxHighlighter>
79
- </div>
80
- );
81
- };
82
-
83
- export default {
84
- title: 'plugin-sheet/functions',
85
- decorators: [
86
- withClientProvider({ types: [FunctionType, SheetType], createIdentity: true, createSpace: true }),
87
- withComputeGraphDecorator({ plugins: testPlugins }),
88
- withTheme,
89
- ],
90
- render: (args: any) => <Story {...args} />,
91
- };
92
-
93
- export const Default = {};
@@ -1,127 +0,0 @@
1
- //
2
- // Copyright 2024 DXOS.org
3
- //
4
-
5
- import { type CellValue } from 'hyperformula';
6
- import { afterEach, beforeEach, describe, expect, test } from 'vitest';
7
-
8
- import { Trigger } from '@dxos/async';
9
- import { Client } from '@dxos/client';
10
- import { create, fullyQualifiedId } from '@dxos/client/echo';
11
- import { Context } from '@dxos/context';
12
- import { type S } from '@dxos/echo-schema';
13
- import { FunctionType } from '@dxos/plugin-script/types';
14
-
15
- import { ComputeGraphRegistry } from './compute-graph';
16
- import { testPlugins } from './testing';
17
- import { addressFromA1Notation, createSheet } from '../defs';
18
- import { SheetModel } from '../model';
19
- import { type CellScalarValue } from '../types';
20
-
21
- /**
22
- * NOTE: Browser test required for hyperformula due to raw translation files.
23
- */
24
- describe('compute graph', () => {
25
- let ctx: Context;
26
- beforeEach(() => {
27
- ctx = new Context();
28
- });
29
- afterEach(async () => {
30
- await ctx.dispose();
31
- });
32
-
33
- // TODO(burdon): Replace with builder.
34
- const createModel = async (types?: S.Schema<any>[]) => {
35
- const client = new Client();
36
- if (types) {
37
- // TODO(burdon): Add to config.
38
- client.addTypes(types);
39
- }
40
- await client.initialize();
41
- await client.halo.createIdentity();
42
- const space = await client.spaces.create();
43
- ctx.onDispose(() => client.destroy());
44
-
45
- const registry = new ComputeGraphRegistry({ plugins: testPlugins });
46
- await registry.open();
47
- ctx.onDispose(() => registry.close());
48
-
49
- const graph = await registry.createGraph(space);
50
-
51
- const sheet = createSheet({ rows: 5, columns: 5 });
52
- const model = new SheetModel(graph, sheet);
53
- await model.open();
54
-
55
- return { space, graph, model };
56
- };
57
-
58
- test('map functions', async () => {
59
- const { space, graph } = await createModel([FunctionType]);
60
-
61
- // Create script.
62
- const trigger = new Trigger();
63
- graph.update.once(() => trigger.wake());
64
- const fn = space.db.add(create(FunctionType, { version: 1, binding: 'TEST' }));
65
- await trigger.wait();
66
- expect(graph.getFunctions({ echo: true })).to.toHaveLength(1);
67
-
68
- const id = graph.mapFunctionBindingToId('TEST()');
69
- expect(id).to.eq(`${fullyQualifiedId(fn)}()`);
70
- });
71
-
72
- test('cross-node references', async () => {
73
- const { graph } = await createModel();
74
-
75
- // Create nodes.
76
- const node1 = await graph.getOrCreateNode('node-1');
77
- const node2 = await graph.getOrCreateNode('node-2');
78
-
79
- {
80
- expect(graph.hf.getSheetNames()).to.toHaveLength(3);
81
- node1.graph.hf.setCellContents({ sheet: node1.sheetId, row: 0, col: 0 }, [[100, 200, 300, '=SUM(A1:C1)']]);
82
- node2.graph.hf.setCellContents({ sheet: node2.sheetId, row: 0, col: 0 }, "='node-1'!D1");
83
- const value1 = node1.graph.hf.getCellValue({ sheet: node1.sheetId, col: 3, row: 0 });
84
- const value2 = node2.graph.hf.getCellValue({ sheet: node2.sheetId, col: 0, row: 0 });
85
- expect(value1).to.eq(value2);
86
- }
87
-
88
- // Get updated event.
89
- const trigger = new Trigger<CellValue>();
90
- node2.update.on(({ change }) => {
91
- const value = node2.graph.hf.getCellValue({ sheet: node2.sheetId, col: 0, row: 0 });
92
- expect(value).to.eq(change?.newValue);
93
- trigger.wake(value);
94
- });
95
-
96
- {
97
- node1.graph.hf.setCellContents({ sheet: node1.sheetId, row: 0, col: 0 }, 400);
98
- const value1 = node1.graph.hf.getCellValue({ sheet: node1.sheetId, col: 3, row: 0 });
99
- const value2 = await trigger.wait();
100
- expect(value1).to.eq(value2);
101
- }
102
- });
103
-
104
- test('async function', async () => {
105
- const { graph, model } = await createModel();
106
-
107
- // Triggers function.
108
- model.setValue(addressFromA1Notation('A1'), '=TEST()');
109
- const trigger = new Trigger<CellScalarValue>();
110
- model.update.once(({ type }) => {
111
- if (type === 'valuesUpdated') {
112
- const value = model.getValue(addressFromA1Notation('A1'));
113
- trigger.wake(value);
114
- }
115
- });
116
-
117
- // Get initial value (null).
118
- const v1 = model.getValue(addressFromA1Notation('A1'));
119
- expect(v1).to.be.null;
120
- expect(graph.context.info.invocations.TEST).to.eq(undefined);
121
-
122
- // Wait until async update triggered.
123
- const v2 = await trigger.wait();
124
- expect(v2).not.to.be.null;
125
- expect(graph.context.info.invocations.TEST).to.eq(1);
126
- });
127
- });