@dxos/plugin-sheet 0.6.12-main.5cc132e → 0.6.12-main.c4a728f

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 (256) hide show
  1. package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs +261 -0
  2. package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-GNNVBNCX.mjs → chunk-6ZMQVB4Z.mjs} +358 -678
  4. package/dist/lib/browser/chunk-6ZMQVB4Z.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-JRL5LGCE.mjs → chunk-QILRZNE5.mjs} +2 -5
  6. package/dist/lib/browser/chunk-QILRZNE5.mjs.map +7 -0
  7. package/dist/lib/{node-esm/chunk-WUPTZUTX.mjs → browser/chunk-T3NJFTD4.mjs} +4 -14
  8. package/dist/lib/browser/chunk-T3NJFTD4.mjs.map +7 -0
  9. package/dist/lib/browser/{SheetContainer-Y7ZMFBAP.mjs → chunk-U2JHW3L6.mjs} +819 -498
  10. package/dist/lib/browser/chunk-U2JHW3L6.mjs.map +7 -0
  11. package/dist/lib/browser/graph-T27BOBOV.mjs +21 -0
  12. package/dist/lib/browser/graph-T27BOBOV.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +58 -55
  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/types.mjs +4 -6
  18. package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs +279 -0
  19. package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs.map +7 -0
  20. package/dist/lib/node/{chunk-BJ6ZD7MN.cjs → chunk-BNARJ5GM.cjs} +5 -18
  21. package/dist/lib/node/chunk-BNARJ5GM.cjs.map +7 -0
  22. package/dist/lib/node/{chunk-ZRQZFV5T.cjs → chunk-DD6FIXWC.cjs} +359 -679
  23. package/dist/lib/node/chunk-DD6FIXWC.cjs.map +7 -0
  24. package/dist/lib/node/{SheetContainer-KEOKUKAQ.cjs → chunk-OTTD7FBK.cjs} +875 -551
  25. package/dist/lib/node/chunk-OTTD7FBK.cjs.map +7 -0
  26. package/dist/lib/node/{chunk-VJU3NPUJ.cjs → chunk-Q3HBHPRL.cjs} +8 -19
  27. package/dist/lib/node/chunk-Q3HBHPRL.cjs.map +7 -0
  28. package/dist/lib/node/graph-SPKGX7W4.cjs +43 -0
  29. package/dist/lib/node/graph-SPKGX7W4.cjs.map +7 -0
  30. package/dist/lib/node/index.cjs +75 -64
  31. package/dist/lib/node/index.cjs.map +3 -3
  32. package/dist/lib/node/meta.cjs +3 -3
  33. package/dist/lib/node/meta.cjs.map +1 -1
  34. package/dist/lib/node/meta.json +1 -1
  35. package/dist/lib/node/types.cjs +10 -12
  36. package/dist/lib/node/types.cjs.map +2 -2
  37. package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs +262 -0
  38. package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs.map +7 -0
  39. package/dist/lib/node-esm/{SheetContainer-Y7ZMFBAP.mjs → chunk-7HVSOTGA.mjs} +820 -498
  40. package/dist/lib/node-esm/chunk-7HVSOTGA.mjs.map +7 -0
  41. package/dist/lib/{browser/chunk-WUPTZUTX.mjs → node-esm/chunk-BMNA27EX.mjs} +5 -14
  42. package/dist/lib/node-esm/chunk-BMNA27EX.mjs.map +7 -0
  43. package/dist/lib/node-esm/{chunk-GNNVBNCX.mjs → chunk-D6KU5MI7.mjs} +359 -677
  44. package/dist/lib/node-esm/chunk-D6KU5MI7.mjs.map +7 -0
  45. package/dist/lib/node-esm/{chunk-JRL5LGCE.mjs → chunk-IU2L277A.mjs} +4 -5
  46. package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +7 -0
  47. package/dist/lib/node-esm/graph-U67IO4UC.mjs +22 -0
  48. package/dist/lib/node-esm/graph-U67IO4UC.mjs.map +7 -0
  49. package/dist/lib/node-esm/index.mjs +59 -55
  50. package/dist/lib/node-esm/index.mjs.map +3 -3
  51. package/dist/lib/node-esm/meta.json +1 -1
  52. package/dist/lib/node-esm/meta.mjs +2 -1
  53. package/dist/lib/node-esm/types.mjs +5 -6
  54. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  55. package/dist/types/src/components/CellEditor/CellEditor.d.ts +23 -3
  56. package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +1 -1
  57. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts +2 -2
  58. package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +1 -1
  59. package/dist/types/src/components/CellEditor/extension.d.ts +1 -1
  60. package/dist/types/src/components/CellEditor/extension.d.ts.map +1 -1
  61. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +11 -0
  62. package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -0
  63. package/dist/types/src/components/ComputeGraph/index.d.ts +1 -3
  64. package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
  65. package/dist/types/src/components/GridSheet/GridSheet.d.ts +10 -0
  66. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -0
  67. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +9 -0
  68. package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -0
  69. package/dist/types/src/components/GridSheet/util.d.ts +7 -0
  70. package/dist/types/src/components/GridSheet/util.d.ts.map +1 -0
  71. package/dist/types/src/components/Sheet/Sheet.d.ts +1 -1
  72. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
  73. package/dist/types/src/components/Sheet/Sheet.stories.d.ts +5 -6
  74. package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -1
  75. package/dist/types/src/components/Sheet/grid.d.ts +2 -2
  76. package/dist/types/src/components/Sheet/grid.d.ts.map +1 -1
  77. package/dist/types/src/components/Sheet/nav.d.ts +3 -3
  78. package/dist/types/src/components/Sheet/nav.d.ts.map +1 -1
  79. package/dist/types/src/components/Sheet/sheet-context.d.ts +4 -5
  80. package/dist/types/src/components/Sheet/sheet-context.d.ts.map +1 -1
  81. package/dist/types/src/components/Sheet/threads.d.ts.map +1 -1
  82. package/dist/types/src/components/SheetContainer.d.ts +1 -1
  83. package/dist/types/src/components/SheetContainer.d.ts.map +1 -1
  84. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  85. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +1 -1
  86. package/dist/types/src/components/index.d.ts +2 -1
  87. package/dist/types/src/components/index.d.ts.map +1 -1
  88. package/dist/types/src/defs/index.d.ts +3 -0
  89. package/dist/types/src/defs/index.d.ts.map +1 -0
  90. package/dist/types/src/{model → defs}/types.d.ts +8 -3
  91. package/dist/types/src/defs/types.d.ts.map +1 -0
  92. package/dist/types/src/defs/types.test.d.ts.map +1 -0
  93. package/dist/types/src/{model → defs}/util.d.ts +8 -4
  94. package/dist/types/src/defs/util.d.ts.map +1 -0
  95. package/dist/types/src/extensions/compute.d.ts +5 -0
  96. package/dist/types/src/extensions/compute.d.ts.map +1 -0
  97. package/dist/types/src/extensions/compute.stories.d.ts +26 -0
  98. package/dist/types/src/extensions/compute.stories.d.ts.map +1 -0
  99. package/dist/types/src/extensions/index.d.ts +2 -0
  100. package/dist/types/src/extensions/index.d.ts.map +1 -0
  101. package/dist/types/src/{components/ComputeGraph → graph}/async-function.d.ts +1 -1
  102. package/dist/types/src/graph/async-function.d.ts.map +1 -0
  103. package/dist/types/src/graph/compute-graph.browser.test.d.ts +2 -0
  104. package/dist/types/src/graph/compute-graph.browser.test.d.ts.map +1 -0
  105. package/dist/types/src/graph/compute-graph.d.ts +81 -0
  106. package/dist/types/src/graph/compute-graph.d.ts.map +1 -0
  107. package/dist/types/src/graph/compute-graph.stories.d.ts +10 -0
  108. package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -0
  109. package/dist/types/src/graph/compute-node.d.ts +19 -0
  110. package/dist/types/src/graph/compute-node.d.ts.map +1 -0
  111. package/dist/types/src/{components/ComputeGraph/custom.d.ts → graph/custom-function.d.ts} +1 -1
  112. package/dist/types/src/graph/custom-function.d.ts.map +1 -0
  113. package/dist/types/src/graph/edge-function.d.ts.map +1 -0
  114. package/dist/types/src/{model/functions.d.ts → graph/function-defs.d.ts} +1 -1
  115. package/dist/types/src/graph/function-defs.d.ts.map +1 -0
  116. package/dist/types/src/graph/hyperformula.test.d.ts +2 -0
  117. package/dist/types/src/graph/hyperformula.test.d.ts.map +1 -0
  118. package/dist/types/src/graph/index.d.ts +4 -0
  119. package/dist/types/src/graph/index.d.ts.map +1 -0
  120. package/dist/types/src/graph/util.d.ts +2 -0
  121. package/dist/types/src/graph/util.d.ts.map +1 -0
  122. package/dist/types/src/hooks/hooks.stories.d.ts +11 -0
  123. package/dist/types/src/hooks/hooks.stories.d.ts.map +1 -0
  124. package/dist/types/src/hooks/index.d.ts +4 -0
  125. package/dist/types/src/hooks/index.d.ts.map +1 -0
  126. package/dist/types/src/hooks/useComputeGraph.d.ts +7 -0
  127. package/dist/types/src/hooks/useComputeGraph.d.ts.map +1 -0
  128. package/dist/types/src/hooks/useFormattingModel.d.ts +3 -0
  129. package/dist/types/src/hooks/useFormattingModel.d.ts.map +1 -0
  130. package/dist/types/src/hooks/useSheetModel.d.ts +8 -0
  131. package/dist/types/src/hooks/useSheetModel.d.ts.map +1 -0
  132. package/dist/types/src/meta.d.ts +1 -4
  133. package/dist/types/src/meta.d.ts.map +1 -1
  134. package/dist/types/src/model/formatting-model.d.ts +16 -0
  135. package/dist/types/src/model/formatting-model.d.ts.map +1 -0
  136. package/dist/types/src/model/index.d.ts +2 -4
  137. package/dist/types/src/model/index.d.ts.map +1 -1
  138. package/dist/types/src/model/{model.d.ts → sheet-model.d.ts} +9 -48
  139. package/dist/types/src/model/sheet-model.d.ts.map +1 -0
  140. package/dist/types/src/sanity.test.d.ts +2 -0
  141. package/dist/types/src/sanity.test.d.ts.map +1 -0
  142. package/dist/types/src/testing/index.d.ts +2 -0
  143. package/dist/types/src/testing/index.d.ts.map +1 -0
  144. package/dist/types/src/testing/testing.d.ts +9 -0
  145. package/dist/types/src/testing/testing.d.ts.map +1 -0
  146. package/dist/types/src/types.d.ts +12 -2
  147. package/dist/types/src/types.d.ts.map +1 -1
  148. package/dist/vendor/hyperformula.mjs +37145 -0
  149. package/package.json +41 -38
  150. package/src/SheetPlugin.tsx +39 -59
  151. package/src/components/CellEditor/CellEditor.stories.tsx +4 -3
  152. package/src/components/CellEditor/CellEditor.tsx +59 -9
  153. package/src/components/CellEditor/extension.test.ts +3 -3
  154. package/src/components/CellEditor/extension.ts +1 -3
  155. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +20 -0
  156. package/src/components/ComputeGraph/index.ts +1 -3
  157. package/src/components/GridSheet/GridSheet.stories.tsx +35 -0
  158. package/src/components/GridSheet/GridSheet.tsx +153 -0
  159. package/src/components/GridSheet/util.ts +108 -0
  160. package/src/components/Sheet/Sheet.stories.tsx +41 -82
  161. package/src/components/Sheet/Sheet.tsx +12 -10
  162. package/src/components/Sheet/grid.ts +3 -3
  163. package/src/components/Sheet/nav.ts +19 -19
  164. package/src/components/Sheet/sheet-context.tsx +10 -80
  165. package/src/components/Sheet/threads.tsx +10 -6
  166. package/src/components/SheetContainer.tsx +2 -2
  167. package/src/components/Toolbar/Toolbar.tsx +1 -2
  168. package/src/components/index.ts +1 -0
  169. package/src/defs/index.ts +6 -0
  170. package/src/{model → defs}/types.test.ts +7 -7
  171. package/src/{model → defs}/types.ts +23 -14
  172. package/src/{model → defs}/util.ts +49 -17
  173. package/src/extensions/compute.stories.tsx +151 -0
  174. package/src/extensions/compute.ts +98 -0
  175. package/src/extensions/index.ts +5 -0
  176. package/src/{components/ComputeGraph → graph}/async-function.ts +3 -1
  177. package/src/graph/compute-graph.browser.test.ts +104 -0
  178. package/src/graph/compute-graph.stories.tsx +92 -0
  179. package/src/graph/compute-graph.ts +290 -0
  180. package/src/graph/compute-node.ts +51 -0
  181. package/src/{components/ComputeGraph/custom.ts → graph/custom-function.ts} +2 -6
  182. package/src/{components/ComputeGraph → graph}/edge-function.ts +2 -1
  183. package/src/graph/hyperformula.test.ts +15 -0
  184. package/src/graph/index.ts +7 -0
  185. package/src/graph/util.ts +8 -0
  186. package/src/hooks/hooks.stories.tsx +50 -0
  187. package/src/hooks/index.ts +7 -0
  188. package/src/hooks/useComputeGraph.ts +20 -0
  189. package/src/hooks/useFormattingModel.ts +11 -0
  190. package/src/hooks/useSheetModel.ts +43 -0
  191. package/src/meta.tsx +1 -5
  192. package/src/{components/Sheet/formatting.ts → model/formatting-model.ts} +20 -13
  193. package/src/model/index.ts +2 -4
  194. package/src/model/{model.ts → sheet-model.ts} +67 -184
  195. package/src/sanity.test.ts +40 -0
  196. package/src/testing/index.ts +5 -0
  197. package/src/testing/testing.tsx +66 -0
  198. package/src/types.ts +14 -12
  199. package/dist/lib/browser/SheetContainer-Y7ZMFBAP.mjs.map +0 -7
  200. package/dist/lib/browser/chunk-GNNVBNCX.mjs.map +0 -7
  201. package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +0 -7
  202. package/dist/lib/browser/chunk-PGKZPKUD.mjs +0 -175
  203. package/dist/lib/browser/chunk-PGKZPKUD.mjs.map +0 -7
  204. package/dist/lib/browser/chunk-VBF7YENS.mjs +0 -8
  205. package/dist/lib/browser/chunk-VBF7YENS.mjs.map +0 -7
  206. package/dist/lib/browser/chunk-WUPTZUTX.mjs.map +0 -7
  207. package/dist/lib/browser/testing.mjs +0 -92
  208. package/dist/lib/browser/testing.mjs.map +0 -7
  209. package/dist/lib/node/SheetContainer-KEOKUKAQ.cjs.map +0 -7
  210. package/dist/lib/node/chunk-57PB2HPY.cjs +0 -40
  211. package/dist/lib/node/chunk-57PB2HPY.cjs.map +0 -7
  212. package/dist/lib/node/chunk-6LWBQAQZ.cjs +0 -202
  213. package/dist/lib/node/chunk-6LWBQAQZ.cjs.map +0 -7
  214. package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +0 -7
  215. package/dist/lib/node/chunk-VJU3NPUJ.cjs.map +0 -7
  216. package/dist/lib/node/chunk-ZRQZFV5T.cjs.map +0 -7
  217. package/dist/lib/node/testing.cjs +0 -111
  218. package/dist/lib/node/testing.cjs.map +0 -7
  219. package/dist/lib/node-esm/SheetContainer-Y7ZMFBAP.mjs.map +0 -7
  220. package/dist/lib/node-esm/chunk-GNNVBNCX.mjs.map +0 -7
  221. package/dist/lib/node-esm/chunk-JRL5LGCE.mjs.map +0 -7
  222. package/dist/lib/node-esm/chunk-PGKZPKUD.mjs +0 -175
  223. package/dist/lib/node-esm/chunk-PGKZPKUD.mjs.map +0 -7
  224. package/dist/lib/node-esm/chunk-VBF7YENS.mjs +0 -8
  225. package/dist/lib/node-esm/chunk-VBF7YENS.mjs.map +0 -7
  226. package/dist/lib/node-esm/chunk-WUPTZUTX.mjs.map +0 -7
  227. package/dist/lib/node-esm/testing.mjs +0 -92
  228. package/dist/lib/node-esm/testing.mjs.map +0 -7
  229. package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +0 -1
  230. package/dist/types/src/components/ComputeGraph/custom.d.ts.map +0 -1
  231. package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +0 -1
  232. package/dist/types/src/components/ComputeGraph/graph-context.d.ts +0 -12
  233. package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +0 -1
  234. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +0 -2
  235. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +0 -1
  236. package/dist/types/src/components/ComputeGraph/graph.d.ts +0 -26
  237. package/dist/types/src/components/ComputeGraph/graph.d.ts.map +0 -1
  238. package/dist/types/src/components/Sheet/formatting.d.ts +0 -14
  239. package/dist/types/src/components/Sheet/formatting.d.ts.map +0 -1
  240. package/dist/types/src/model/functions.d.ts.map +0 -1
  241. package/dist/types/src/model/model.browser.test.d.ts +0 -2
  242. package/dist/types/src/model/model.browser.test.d.ts.map +0 -1
  243. package/dist/types/src/model/model.d.ts.map +0 -1
  244. package/dist/types/src/model/types.d.ts.map +0 -1
  245. package/dist/types/src/model/types.test.d.ts.map +0 -1
  246. package/dist/types/src/model/util.d.ts.map +0 -1
  247. package/dist/types/src/testing.d.ts +0 -9
  248. package/dist/types/src/testing.d.ts.map +0 -1
  249. package/src/components/ComputeGraph/graph-context.tsx +0 -50
  250. package/src/components/ComputeGraph/graph.browser.test.ts +0 -49
  251. package/src/components/ComputeGraph/graph.ts +0 -62
  252. package/src/model/model.browser.test.ts +0 -99
  253. package/src/testing.ts +0 -50
  254. /package/dist/types/src/{model → defs}/types.test.d.ts +0 -0
  255. /package/dist/types/src/{components/ComputeGraph → graph}/edge-function.d.ts +0 -0
  256. /package/src/{model/functions.ts → graph/function-defs.ts} +0 -0
@@ -2,40 +2,29 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { DetailedCellError, ExportedCellChange } from 'hyperformula';
6
5
  import { type SimpleCellRange } from 'hyperformula/typings/AbsoluteCellRange';
7
6
  import { type SimpleCellAddress } from 'hyperformula/typings/Cell';
8
7
  import { type SimpleDate, type SimpleDateTime } from 'hyperformula/typings/DateTimeHelper';
9
8
 
10
9
  import { Event } from '@dxos/async';
11
- import { type Space } from '@dxos/client/echo';
12
- import { Context } from '@dxos/context';
10
+ import { Resource } from '@dxos/context';
13
11
  import { invariant } from '@dxos/invariant';
14
12
  import { PublicKey } from '@dxos/keys';
15
13
  import { log } from '@dxos/log';
16
- import { type FunctionType } from '@dxos/plugin-script/types';
17
14
 
18
- import { defaultFunctions, type FunctionDefinition } from './functions';
19
- import { addressFromA1Notation, addressToA1Notation, type CellAddress, type CellRange } from './types';
20
- import { addressFromIndex, addressToIndex, createIndices, RangeException, ReadonlyException } from './util';
21
- import { type ComputeGraph } from '../components';
15
+ import { DetailedCellError, ExportedCellChange } from '#hyperformula';
16
+ import {
17
+ addressFromA1Notation,
18
+ addressToA1Notation,
19
+ type CellAddress,
20
+ type CellRange,
21
+ MAX_COLUMNS,
22
+ MAX_ROWS,
23
+ } from '../defs';
24
+ import { addressFromIndex, addressToIndex, initialize, insertIndices, ReadonlyException } from '../defs';
25
+ import { type ComputeNode, type ComputeGraph, createSheetName } from '../graph';
22
26
  import { type CellScalarValue, type CellValue, type SheetType, ValueTypeEnum } from '../types';
23
27
 
24
- const DEFAULT_ROWS = 100;
25
- const DEFAULT_COLUMNS = 26;
26
-
27
- export type CellIndex = string;
28
-
29
- export type CellContentValue = number | string | boolean | null;
30
-
31
- export type SheetModelOptions = {
32
- readonly?: boolean;
33
- rows: number;
34
- columns: number;
35
- mapFormulaBindingToId: (functions: FunctionType[]) => (formula: string) => string;
36
- mapFormulaBindingFromId: (functions: FunctionType[]) => (formula: string) => string;
37
- };
38
-
39
28
  const typeMap: Record<string, ValueTypeEnum> = {
40
29
  BOOLEAN: ValueTypeEnum.Boolean,
41
30
  NUMBER_RAW: ValueTypeEnum.Number,
@@ -46,22 +35,15 @@ const typeMap: Record<string, ValueTypeEnum> = {
46
35
  NUMBER_TIME: ValueTypeEnum.Time,
47
36
  };
48
37
 
49
- export const defaultOptions: SheetModelOptions = {
50
- rows: 50,
51
- columns: 26,
52
- mapFormulaBindingFromId: () => (formula) => formula,
53
- mapFormulaBindingToId: () => (formula) => formula,
54
- };
55
-
56
- const getTopLeft = (range: CellRange) => {
38
+ const getTopLeft = (range: CellRange): CellAddress => {
57
39
  const to = range.to ?? range.from;
58
- return { row: Math.min(range.from.row, to.row), column: Math.min(range.from.column, to.column) };
40
+ return { row: Math.min(range.from.row, to.row), col: Math.min(range.from.col, to.col) };
59
41
  };
60
42
 
61
43
  const toSimpleCellAddress = (sheet: number, cell: CellAddress): SimpleCellAddress => ({
62
44
  sheet,
63
45
  row: cell.row,
64
- col: cell.column,
46
+ col: cell.col,
65
47
  });
66
48
 
67
49
  const toModelRange = (sheet: number, range: CellRange): SimpleCellRange => ({
@@ -69,38 +51,31 @@ const toModelRange = (sheet: number, range: CellRange): SimpleCellRange => ({
69
51
  end: toSimpleCellAddress(sheet, range.to ?? range.from),
70
52
  });
71
53
 
54
+ export type SheetModelOptions = {
55
+ readonly?: boolean;
56
+ };
57
+
72
58
  /**
73
59
  * Spreadsheet data model.
74
60
  *
75
61
  * [ComputeGraphContext] > [SheetContext]:[SheetModel] > [Sheet.Root]
76
62
  */
77
- export class SheetModel {
63
+ // TODO(burdon): Factor out commonality with ComputeNode.
64
+ export class SheetModel extends Resource {
78
65
  public readonly id = `model-${PublicKey.random().truncate()}`;
79
- private _ctx?: Context = undefined;
80
-
81
- /**
82
- * Formula engine.
83
- * Acts as a write through cache for scalar and computed values.
84
- */
85
- private readonly _sheetId: number;
86
- private readonly _options: SheetModelOptions;
87
- private _functions: FunctionType[] = [];
88
66
 
89
67
  public readonly update = new Event();
90
68
 
69
+ private readonly _node: ComputeNode;
70
+
91
71
  constructor(
92
72
  private readonly _graph: ComputeGraph,
93
73
  private readonly _sheet: SheetType,
94
- private readonly _space?: Space,
95
- options: Partial<SheetModelOptions> = {},
74
+ private readonly _options: SheetModelOptions = {},
96
75
  ) {
97
- // Sheet for this object.
98
- const name = this._sheet.id;
99
- if (!this._graph.hf.doesSheetExist(name)) {
100
- this._graph.hf.addSheet(name);
101
- }
102
- this._sheetId = this._graph.hf.getSheetId(name)!;
103
- this._options = { ...defaultOptions, ...options };
76
+ super();
77
+ // TODO(burdon): SheetModel should extend ComputeNode and be constructed via the graph.
78
+ this._node = this._graph.getOrCreateNode(createSheetName(this._sheet.id));
104
79
  this.reset();
105
80
  }
106
81
 
@@ -123,59 +98,18 @@ export class SheetModel {
123
98
  };
124
99
  }
125
100
 
126
- get functions(): FunctionDefinition[] {
127
- const hfFunctions = this._graph.hf
128
- .getRegisteredFunctionNames()
129
- .map((name) => defaultFunctions.find((fn) => fn.name === name) ?? { name });
130
- const echoFunctions = this._functions.map((fn) => ({ name: fn.binding! }));
131
- return [...hfFunctions, ...echoFunctions];
132
- }
133
-
134
- get initialized(): boolean {
135
- return !!this._ctx;
136
- }
137
-
138
101
  /**
139
102
  * Initialize sheet and engine.
140
103
  */
141
- async initialize() {
104
+ protected override async _open() {
142
105
  log('initialize', { id: this.id });
143
- invariant(!this.initialized, 'Already initialized.');
144
- this._ctx = new Context();
145
- if (!this._sheet.rows.length) {
146
- this._insertIndices(this._sheet.rows, 0, this._options.rows, DEFAULT_ROWS);
147
- }
148
- if (!this._sheet.columns.length) {
149
- this._insertIndices(this._sheet.columns, 0, this._options.columns, DEFAULT_COLUMNS);
150
- }
106
+ initialize(this._sheet);
151
107
  this.reset();
152
108
 
109
+ // TODO(burdon): Event hierarchy?
153
110
  // Listen for model updates (e.g., async calculations).
154
111
  const unsubscribe = this._graph.update.on(() => this.update.emit());
155
112
  this._ctx.onDispose(unsubscribe);
156
-
157
- if (this._space) {
158
- const { Filter } = await import('@dxos/client/echo');
159
- const { FunctionType } = await import('@dxos/plugin-script/types');
160
-
161
- // Listen for function changes.
162
- const query = this._space?.db.query(Filter.schema(FunctionType));
163
- const unsubscribe = query.subscribe(({ objects }) => {
164
- this._functions = objects.filter((fn) => fn.binding);
165
- this.update.emit();
166
- });
167
- this._ctx.onDispose(unsubscribe);
168
- }
169
-
170
- return this;
171
- }
172
-
173
- async destroy() {
174
- log('destroy', { id: this.id });
175
- if (this._ctx) {
176
- await this._ctx.dispose();
177
- this._ctx = undefined;
178
- }
179
113
  }
180
114
 
181
115
  /**
@@ -184,14 +118,16 @@ export class SheetModel {
184
118
  * @deprecated
185
119
  */
186
120
  reset() {
187
- this._graph.hf.clearSheet(this._sheetId);
121
+ this._node.hf.clearSheet(this._node.sheetId);
188
122
  Object.entries(this._sheet.cells).forEach(([key, { value }]) => {
189
- const { column, row } = addressFromIndex(this._sheet, key);
123
+ const { col, row } = addressFromIndex(this._sheet, key);
190
124
  if (typeof value === 'string' && value.charAt(0) === '=') {
191
- value = this.mapFormulaBindingToFormula(this.mapFormulaBindingFromId(this.mapFormulaIndicesToRefs(value)));
125
+ value = this._graph.mapFormulaToNative(
126
+ this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value)),
127
+ );
192
128
  }
193
129
 
194
- this._graph.hf.setCellContents({ sheet: this._sheetId, row, col: column }, value);
130
+ this._node.hf.setCellContents({ sheet: this._node.sheetId, row, col }, value);
195
131
  });
196
132
  }
197
133
 
@@ -203,16 +139,16 @@ export class SheetModel {
203
139
  */
204
140
  // TODO(burdon): Remove.
205
141
  recalculate() {
206
- this._graph.hf.rebuildAndRecalculate();
142
+ this._node.hf.rebuildAndRecalculate();
207
143
  }
208
144
 
209
145
  insertRows(i: number, n = 1) {
210
- this._insertIndices(this._sheet.rows, i, n, DEFAULT_ROWS);
146
+ insertIndices(this._sheet.rows, i, n, MAX_ROWS);
211
147
  this.reset();
212
148
  }
213
149
 
214
150
  insertColumns(i: number, n = 1) {
215
- this._insertIndices(this._sheet.columns, i, n, DEFAULT_COLUMNS);
151
+ insertIndices(this._sheet.columns, i, n, MAX_COLUMNS);
216
152
  this.reset();
217
153
  }
218
154
 
@@ -220,13 +156,14 @@ export class SheetModel {
220
156
  // Undoable actions.
221
157
  // TODO(burdon): Group undoable methods; consistently update hf/sheet.
222
158
  //
159
+
223
160
  /**
224
161
  * Clear range of values.
225
162
  */
226
163
  clear(range: CellRange) {
227
164
  const topLeft = getTopLeft(range);
228
165
  const values = this._iterRange(range, () => null);
229
- this._graph.hf.setCellContents(toSimpleCellAddress(this._sheetId, topLeft), values);
166
+ this._node.hf.setCellContents(toSimpleCellAddress(this._node.sheetId, topLeft), values);
230
167
  this._iterRange(range, (cell) => {
231
168
  const idx = addressToIndex(this._sheet, cell);
232
169
  delete this._sheet.cells[idx];
@@ -234,7 +171,7 @@ export class SheetModel {
234
171
  }
235
172
 
236
173
  cut(range: CellRange) {
237
- this._graph.hf.cut(toModelRange(this._sheetId, range));
174
+ this._node.hf.cut(toModelRange(this._node.sheetId, range));
238
175
  this._iterRange(range, (cell) => {
239
176
  const idx = addressToIndex(this._sheet, cell);
240
177
  delete this._sheet.cells[idx];
@@ -242,16 +179,16 @@ export class SheetModel {
242
179
  }
243
180
 
244
181
  copy(range: CellRange) {
245
- this._graph.hf.copy(toModelRange(this._sheetId, range));
182
+ this._node.hf.copy(toModelRange(this._node.sheetId, range));
246
183
  }
247
184
 
248
185
  paste(cell: CellAddress) {
249
- if (!this._graph.hf.isClipboardEmpty()) {
250
- const changes = this._graph.hf.paste(toSimpleCellAddress(this._sheetId, cell));
186
+ if (!this._node.hf.isClipboardEmpty()) {
187
+ const changes = this._node.hf.paste(toSimpleCellAddress(this._node.sheetId, cell));
251
188
  for (const change of changes) {
252
189
  if (change instanceof ExportedCellChange) {
253
190
  const { address, newValue } = change;
254
- const idx = addressToIndex(this._sheet, { row: address.row, column: address.col });
191
+ const idx = addressToIndex(this._sheet, { row: address.row, col: address.col });
255
192
  this._sheet.cells[idx] = { value: newValue };
256
193
  }
257
194
  }
@@ -260,15 +197,15 @@ export class SheetModel {
260
197
 
261
198
  // TODO(burdon): Display undo/redo state.
262
199
  undo() {
263
- if (this._graph.hf.isThereSomethingToUndo()) {
264
- this._graph.hf.undo();
200
+ if (this._node.hf.isThereSomethingToUndo()) {
201
+ this._node.hf.undo();
265
202
  this.update.emit();
266
203
  }
267
204
  }
268
205
 
269
206
  redo() {
270
- if (this._graph.hf.isThereSomethingToRedo()) {
271
- this._graph.hf.redo();
207
+ if (this._node.hf.isThereSomethingToRedo()) {
208
+ this._node.hf.redo();
272
209
  this.update.emit();
273
210
  }
274
211
  }
@@ -291,7 +228,7 @@ export class SheetModel {
291
228
  }
292
229
 
293
230
  if (typeof value === 'string' && value.charAt(0) === '=') {
294
- return this.mapFormulaBindingFromId(this.mapFormulaIndicesToRefs(value));
231
+ return this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value));
295
232
  } else {
296
233
  return String(value);
297
234
  }
@@ -309,7 +246,7 @@ export class SheetModel {
309
246
  */
310
247
  getValue(cell: CellAddress): CellScalarValue {
311
248
  // Applies rounding and post-processing.
312
- const value = this._graph.hf.getCellValue(toSimpleCellAddress(this._sheetId, cell));
249
+ const value = this._node.hf.getCellValue(toSimpleCellAddress(this._node.sheetId, cell));
313
250
  if (value instanceof DetailedCellError) {
314
251
  return value.toString();
315
252
  }
@@ -321,8 +258,8 @@ export class SheetModel {
321
258
  * Get value type.
322
259
  */
323
260
  getValueType(cell: CellAddress): ValueTypeEnum {
324
- const addr = toSimpleCellAddress(this._sheetId, cell);
325
- const type = this._graph.hf.getCellValueDetailedType(addr);
261
+ const addr = toSimpleCellAddress(this._node.sheetId, cell);
262
+ const type = this._node.hf.getCellValueDetailedType(addr);
326
263
  return typeMap[type];
327
264
  }
328
265
 
@@ -337,21 +274,22 @@ export class SheetModel {
337
274
  // Reallocate if > current bounds.
338
275
  let refresh = false;
339
276
  if (cell.row >= this._sheet.rows.length) {
340
- this._insertIndices(this._sheet.rows, cell.row, 1, DEFAULT_ROWS);
277
+ insertIndices(this._sheet.rows, cell.row, 1, MAX_ROWS);
341
278
  refresh = true;
342
279
  }
343
- if (cell.column >= this._sheet.columns.length) {
344
- this._insertIndices(this._sheet.columns, cell.column, 1, DEFAULT_COLUMNS);
280
+ if (cell.col >= this._sheet.columns.length) {
281
+ insertIndices(this._sheet.columns, cell.col, 1, MAX_COLUMNS);
345
282
  refresh = true;
346
283
  }
284
+
347
285
  if (refresh) {
348
286
  // TODO(burdon): Remove.
349
287
  this.reset();
350
288
  }
351
289
 
352
290
  // Insert into engine.
353
- this._graph.hf.setCellContents({ sheet: this._sheetId, row: cell.row, col: cell.column }, [
354
- [typeof value === 'string' && value.charAt(0) === '=' ? this.mapFormulaBindingToFormula(value) : value],
291
+ this._node.hf.setCellContents({ sheet: this._node.sheetId, row: cell.row, col: cell.col }, [
292
+ [typeof value === 'string' && value.charAt(0) === '=' ? this._graph.mapFormulaToNative(value) : value],
355
293
  ]);
356
294
 
357
295
  // Insert into sheet.
@@ -360,7 +298,7 @@ export class SheetModel {
360
298
  delete this._sheet.cells[idx];
361
299
  } else {
362
300
  if (typeof value === 'string' && value.charAt(0) === '=') {
363
- value = this.mapFormulaBindingToId(this.mapFormulaRefsToIndices(value));
301
+ value = this._graph.mapFunctionBindingToId(this.mapFormulaRefsToIndices(value));
364
302
  }
365
303
 
366
304
  this._sheet.cells[idx] = { value };
@@ -382,35 +320,23 @@ export class SheetModel {
382
320
  private _iterRange(range: CellRange, cb: (cell: CellAddress) => CellScalarValue | void): CellScalarValue[][] {
383
321
  const to = range.to ?? range.from;
384
322
  const rowRange = [Math.min(range.from.row, to.row), Math.max(range.from.row, to.row)];
385
- const columnRange = [Math.min(range.from.column, to.column), Math.max(range.from.column, to.column)];
323
+ const columnRange = [Math.min(range.from.col, to.col), Math.max(range.from.col, to.col)];
386
324
  const rows: CellScalarValue[][] = [];
387
325
  for (let row = rowRange[0]; row <= rowRange[1]; row++) {
388
326
  const rowCells: CellScalarValue[] = [];
389
327
  for (let column = columnRange[0]; column <= columnRange[1]; column++) {
390
- const value = cb({ row, column });
328
+ const value = cb({ row, col: column });
391
329
  if (value !== undefined) {
392
330
  rowCells.push(value);
393
331
  }
394
332
  }
333
+
395
334
  rows.push(rowCells);
396
335
  }
397
336
 
398
337
  return rows;
399
338
  }
400
339
 
401
- /**
402
- *
403
- */
404
- // TODO(burdon): Insert indices into sheet.
405
- private _insertIndices(indices: string[], i: number, n: number, max: number) {
406
- if (i + n > max) {
407
- throw new RangeException(i + n);
408
- }
409
-
410
- const idx = createIndices(n);
411
- indices.splice(i, 0, ...idx);
412
- }
413
-
414
340
  // TODO(burdon): Delete index.
415
341
  private _deleteIndices(indices: string[], i: number, n: number) {
416
342
  throw new Error('Not implemented');
@@ -425,49 +351,6 @@ export class SheetModel {
425
351
  // Indices.
426
352
  //
427
353
 
428
- /**
429
- * E.g., "HELLO()" => "EDGE("HELLO")".
430
- */
431
- mapFormulaBindingToFormula(formula: string): string {
432
- return formula.replace(/([a-zA-Z0-9]+)\((.*)\)/g, (match, binding, args) => {
433
- const fn = this._functions.find((fn) => fn.binding === binding);
434
- if (!fn) {
435
- return match;
436
- }
437
-
438
- if (args.trim() === '') {
439
- return `EDGE("${binding}")`;
440
- }
441
- return `EDGE("${binding}", ${args})`;
442
- });
443
- }
444
-
445
- /**
446
- * E.g., "EDGE("HELLO")" => "HELLO()".
447
- */
448
- mapFormulaBindingFromFormula(formula: string): string {
449
- return formula.replace(/EDGE\("([a-zA-Z0-9]+)"(.*)\)/, (_match, binding, args) => {
450
- if (args.trim() === '') {
451
- return `${binding}()`;
452
- }
453
- return `${binding}(${args.slice(2)})`;
454
- });
455
- }
456
-
457
- /**
458
- * Map from binding to fully qualified ECHO ID.
459
- */
460
- mapFormulaBindingToId(formula: string): string {
461
- return this._options.mapFormulaBindingToId(this._functions)(formula);
462
- }
463
-
464
- /**
465
- * Map from fully qualified ECHO ID to binding.
466
- */
467
- mapFormulaBindingFromId(formula: string): string {
468
- return this._options.mapFormulaBindingFromId(this._functions)(formula);
469
- }
470
-
471
354
  /**
472
355
  * Map from A1 notation to indices.
473
356
  */
@@ -503,14 +386,14 @@ export class SheetModel {
503
386
  }
504
387
 
505
388
  toDateTime(num: number): SimpleDateTime {
506
- return this._graph.hf.numberToDateTime(num) as SimpleDateTime;
389
+ return this._node.hf.numberToDateTime(num) as SimpleDateTime;
507
390
  }
508
391
 
509
392
  toDate(num: number): SimpleDate {
510
- return this._graph.hf.numberToDate(num) as SimpleDate;
393
+ return this._node.hf.numberToDate(num) as SimpleDate;
511
394
  }
512
395
 
513
396
  toTime(num: number): SimpleDate {
514
- return this._graph.hf.numberToTime(num) as SimpleDate;
397
+ return this._node.hf.numberToTime(num) as SimpleDate;
515
398
  }
516
399
  }
@@ -0,0 +1,40 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import { describe, test, expect } from 'vitest';
6
+
7
+ // Part 2.
8
+ // TODO(burdon): Cannot test outside of browser.
9
+ // - Cannot test Hyperformula
10
+ // - throws "Cannot convert undefined or null to object" in vitest (no browser).
11
+ // - throws "process.nextTick is not a function" (if browser)
12
+
13
+ import { Client } from '@dxos/client';
14
+ import { create } from '@dxos/client/echo';
15
+ import { FunctionType } from '@dxos/plugin-script/types';
16
+
17
+ // TODO(burdon): Fix test infrastructure:
18
+ // - Need docs? esp. needed for config. need pristine example package?
19
+ // - NOTE for non browser tests, import types from x-plugin/types (otherwise will bring in react deps).
20
+ // - Can't add flags to our tools?
21
+ // - .only / .skip ignored (have to comment out tests)
22
+
23
+ describe('test', () => {
24
+ test('test', async () => {
25
+ const client = new Client();
26
+ client.addTypes([FunctionType]);
27
+ await client.initialize();
28
+ await client.halo.createIdentity();
29
+
30
+ // Part 1.
31
+ // Create script.
32
+ // VITEST_ENV=chromium p test
33
+ // TODO(burdon): Test after initialize.
34
+ // - ERROR "process.nextTick is not a function"
35
+ // - ERROR "Identifier 'Buffer' has already been declared" if { nodeExternal: true }
36
+ const space = await client.spaces.create();
37
+ const fn = space.db.add(create(FunctionType, { version: 1, binding: 'HELLO' }));
38
+ expect(fn).to.exist;
39
+ });
40
+ });
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ export * from './testing';
@@ -0,0 +1,66 @@
1
+ //
2
+ // Copyright 2024 DXOS.org
3
+ //
4
+
5
+ import type { Decorator } from '@storybook/react';
6
+ import React, { useState } from 'react';
7
+
8
+ import { type Space } from '@dxos/react-client/echo';
9
+ import { useAsyncState } from '@dxos/react-hooks';
10
+
11
+ import { ComputeGraphContextProvider } from '../components';
12
+ import { createSheet } from '../defs';
13
+ import { type ComputeGraph, ComputeGraphRegistry } from '../graph';
14
+ import { type CellValue, type CreateSheetOptions } from '../types';
15
+
16
+ export const testSheetName = 'test';
17
+
18
+ // TODO(thure): Remove this from the `/testing` entrypoint.
19
+ export const createCells = (): Record<string, CellValue> => ({
20
+ B1: { value: 'Qty' },
21
+ B3: { value: 1 },
22
+ B4: { value: 2 },
23
+ B5: { value: 3 },
24
+ B7: { value: 'Total' },
25
+
26
+ C1: { value: 'Price' },
27
+ C3: { value: 2_000 },
28
+ C4: { value: 2_500 },
29
+ C5: { value: 3_000 },
30
+ C7: { value: '=SUMPRODUCT(B2:B6, C2:C6)' },
31
+ // C8: { value: '=C7*CRYPTO(D7)' },
32
+ C8: { value: '=C7*TEST()' },
33
+
34
+ D7: { value: 'USD' },
35
+ D8: { value: 'BTC' },
36
+
37
+ E3: { value: '=TODAY()' },
38
+ E4: { value: '=NOW()' },
39
+
40
+ F1: { value: `=${testSheetName}!A1` }, // Ref test sheet.
41
+ F3: { value: true },
42
+ F4: { value: false },
43
+ F5: { value: '8%' },
44
+ F6: { value: '$10000' },
45
+ });
46
+
47
+ export const useTestSheet = (space?: Space, graph?: ComputeGraph, options?: CreateSheetOptions) => {
48
+ return useAsyncState(async () => {
49
+ if (!space || !graph) {
50
+ return;
51
+ }
52
+
53
+ const sheet = createSheet(options);
54
+ space.db.add(sheet);
55
+ return sheet;
56
+ }, [space, graph]);
57
+ };
58
+
59
+ export const withGraphDecorator: Decorator = (Story) => {
60
+ const [registry] = useState(new ComputeGraphRegistry());
61
+ return (
62
+ <ComputeGraphContextProvider registry={registry}>
63
+ <Story />
64
+ </ComputeGraphContextProvider>
65
+ );
66
+ };
package/src/types.ts CHANGED
@@ -9,8 +9,10 @@ import type {
9
9
  SurfaceProvides,
10
10
  TranslationsProvides,
11
11
  } from '@dxos/app-framework';
12
- import { create, ref, S, TypedObject } from '@dxos/echo-schema';
12
+ import { ref, S, TypedObject } from '@dxos/echo-schema';
13
13
  import { type SchemaProvides } from '@dxos/plugin-client';
14
+ import { type MarkdownExtensionProvides } from '@dxos/plugin-markdown';
15
+ import { type SpaceInitProvides } from '@dxos/plugin-space';
14
16
  import { ThreadType } from '@dxos/plugin-space/types';
15
17
  import { type StackProvides } from '@dxos/plugin-stack';
16
18
 
@@ -35,9 +37,11 @@ type ThreadProvides<T> = {
35
37
  export type SheetPluginProvides = SurfaceProvides &
36
38
  IntentResolverProvides &
37
39
  GraphBuilderProvides &
40
+ MarkdownExtensionProvides &
38
41
  MetadataRecordsProvides &
39
42
  TranslationsProvides &
40
43
  SchemaProvides &
44
+ SpaceInitProvides &
41
45
  StackProvides &
42
46
  ThreadProvides<SheetType>;
43
47
 
@@ -122,14 +126,12 @@ export class SheetType extends TypedObject({ typename: 'dxos.org/type/SheetType'
122
126
  threads: S.optional(S.mutable(S.Array(ref(ThreadType)))),
123
127
  }) {}
124
128
 
125
- // TODO(burdon): Fix defaults.
126
- export const createSheet = (title?: string): SheetType =>
127
- create(SheetType, {
128
- title,
129
- cells: {},
130
- rows: [],
131
- columns: [],
132
- rowMeta: {},
133
- columnMeta: {},
134
- formatting: {},
135
- });
129
+ export type SheetSize = {
130
+ rows: number;
131
+ columns: number;
132
+ };
133
+
134
+ export type CreateSheetOptions = {
135
+ // TODO(burdon): Standardize as name.
136
+ title?: string;
137
+ } & Partial<SheetSize>;