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

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 (273) hide show
  1. package/dist/lib/browser/SheetContainer-T2QWJOFD.mjs +262 -0
  2. package/dist/lib/browser/SheetContainer-T2QWJOFD.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-WUPTZUTX.mjs → chunk-5ZMVZYGB.mjs} +21 -19
  4. package/dist/lib/browser/chunk-5ZMVZYGB.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-GNNVBNCX.mjs → chunk-GSV5QNLD.mjs} +409 -686
  6. package/dist/lib/browser/chunk-GSV5QNLD.mjs.map +7 -0
  7. package/dist/lib/browser/{chunk-JRL5LGCE.mjs → chunk-QILRZNE5.mjs} +2 -5
  8. package/dist/lib/browser/chunk-QILRZNE5.mjs.map +7 -0
  9. package/dist/lib/browser/{SheetContainer-Y7ZMFBAP.mjs → chunk-ZL2V5UJR.mjs} +982 -508
  10. package/dist/lib/browser/chunk-ZL2V5UJR.mjs.map +7 -0
  11. package/dist/lib/browser/graph-M4IQ76QX.mjs +33 -0
  12. package/dist/lib/browser/graph-M4IQ76QX.mjs.map +7 -0
  13. package/dist/lib/browser/index.mjs +86 -59
  14. package/dist/lib/browser/index.mjs.map +4 -4
  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-PV5ET4UJ.cjs +280 -0
  19. package/dist/lib/node/SheetContainer-PV5ET4UJ.cjs.map +7 -0
  20. package/dist/lib/node/{SheetContainer-KEOKUKAQ.cjs → chunk-2K53Z2TU.cjs} +1036 -558
  21. package/dist/lib/node/chunk-2K53Z2TU.cjs.map +7 -0
  22. package/dist/lib/node/{chunk-ZRQZFV5T.cjs → chunk-5XPK2V4A.cjs} +418 -691
  23. package/dist/lib/node/chunk-5XPK2V4A.cjs.map +7 -0
  24. package/dist/lib/node/{chunk-BJ6ZD7MN.cjs → chunk-BNARJ5GM.cjs} +5 -18
  25. package/dist/lib/node/chunk-BNARJ5GM.cjs.map +7 -0
  26. package/dist/lib/node/{chunk-VJU3NPUJ.cjs → chunk-STAVQ2JE.cjs} +25 -24
  27. package/dist/lib/node/chunk-STAVQ2JE.cjs.map +7 -0
  28. package/dist/lib/node/graph-Q3N2X26H.cjs +55 -0
  29. package/dist/lib/node/graph-Q3N2X26H.cjs.map +7 -0
  30. package/dist/lib/node/index.cjs +98 -66
  31. package/dist/lib/node/index.cjs.map +4 -4
  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-FOZD2WLT.mjs +263 -0
  38. package/dist/lib/node-esm/SheetContainer-FOZD2WLT.mjs.map +7 -0
  39. package/dist/lib/node-esm/{chunk-WUPTZUTX.mjs → chunk-2HAM45RC.mjs} +22 -19
  40. package/dist/lib/node-esm/chunk-2HAM45RC.mjs.map +7 -0
  41. package/dist/lib/node-esm/{chunk-GNNVBNCX.mjs → chunk-5WPZCXNS.mjs} +411 -686
  42. package/dist/lib/node-esm/chunk-5WPZCXNS.mjs.map +7 -0
  43. package/dist/lib/node-esm/{chunk-JRL5LGCE.mjs → chunk-IU2L277A.mjs} +4 -5
  44. package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +7 -0
  45. package/dist/lib/node-esm/{SheetContainer-Y7ZMFBAP.mjs → chunk-QEUCIHIN.mjs} +983 -508
  46. package/dist/lib/node-esm/chunk-QEUCIHIN.mjs.map +7 -0
  47. package/dist/lib/node-esm/graph-SMPUMOV2.mjs +34 -0
  48. package/dist/lib/node-esm/graph-SMPUMOV2.mjs.map +7 -0
  49. package/dist/lib/node-esm/index.mjs +87 -59
  50. package/dist/lib/node-esm/index.mjs.map +4 -4
  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 +16 -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 +6 -7
  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 +6 -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/graph/compute-graph-registry.d.ts +34 -0
  102. package/dist/types/src/graph/compute-graph-registry.d.ts.map +1 -0
  103. package/dist/types/src/graph/compute-graph.d.ts +64 -0
  104. package/dist/types/src/graph/compute-graph.d.ts.map +1 -0
  105. package/dist/types/src/graph/compute-graph.stories.d.ts +10 -0
  106. package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -0
  107. package/dist/types/src/graph/compute-graph.test.d.ts +2 -0
  108. package/dist/types/src/graph/compute-graph.test.d.ts.map +1 -0
  109. package/dist/types/src/graph/compute-node.d.ts +26 -0
  110. package/dist/types/src/graph/compute-node.d.ts.map +1 -0
  111. package/dist/types/src/{components/ComputeGraph → graph/functions}/async-function.d.ts +14 -5
  112. package/dist/types/src/graph/functions/async-function.d.ts.map +1 -0
  113. package/dist/types/src/graph/functions/edge-function.d.ts +21 -0
  114. package/dist/types/src/graph/functions/edge-function.d.ts.map +1 -0
  115. package/dist/types/src/{model/functions.d.ts → graph/functions/function-defs.d.ts} +1 -1
  116. package/dist/types/src/graph/functions/function-defs.d.ts.map +1 -0
  117. package/dist/types/src/graph/functions/index.d.ts +4 -0
  118. package/dist/types/src/graph/functions/index.d.ts.map +1 -0
  119. package/dist/types/src/graph/hyperformula.test.d.ts +2 -0
  120. package/dist/types/src/graph/hyperformula.test.d.ts.map +1 -0
  121. package/dist/types/src/graph/index.d.ts +5 -0
  122. package/dist/types/src/graph/index.d.ts.map +1 -0
  123. package/dist/types/src/graph/testing/index.d.ts +3 -0
  124. package/dist/types/src/graph/testing/index.d.ts.map +1 -0
  125. package/dist/types/src/graph/testing/test-builder.d.ts +15 -0
  126. package/dist/types/src/graph/testing/test-builder.d.ts.map +1 -0
  127. package/dist/types/src/graph/testing/test-plugin.d.ts +36 -0
  128. package/dist/types/src/graph/testing/test-plugin.d.ts.map +1 -0
  129. package/dist/types/src/graph/util.d.ts +2 -0
  130. package/dist/types/src/graph/util.d.ts.map +1 -0
  131. package/dist/types/src/hooks/hooks.stories.d.ts +11 -0
  132. package/dist/types/src/hooks/hooks.stories.d.ts.map +1 -0
  133. package/dist/types/src/hooks/index.d.ts +4 -0
  134. package/dist/types/src/hooks/index.d.ts.map +1 -0
  135. package/dist/types/src/hooks/useComputeGraph.d.ts +7 -0
  136. package/dist/types/src/hooks/useComputeGraph.d.ts.map +1 -0
  137. package/dist/types/src/hooks/useFormattingModel.d.ts +3 -0
  138. package/dist/types/src/hooks/useFormattingModel.d.ts.map +1 -0
  139. package/dist/types/src/hooks/useSheetModel.d.ts +8 -0
  140. package/dist/types/src/hooks/useSheetModel.d.ts.map +1 -0
  141. package/dist/types/src/meta.d.ts +1 -4
  142. package/dist/types/src/meta.d.ts.map +1 -1
  143. package/dist/types/src/model/formatting-model.d.ts +16 -0
  144. package/dist/types/src/model/formatting-model.d.ts.map +1 -0
  145. package/dist/types/src/model/index.d.ts +2 -4
  146. package/dist/types/src/model/index.d.ts.map +1 -1
  147. package/dist/types/src/model/{model.d.ts → sheet-model.d.ts} +10 -49
  148. package/dist/types/src/model/sheet-model.d.ts.map +1 -0
  149. package/dist/types/src/model/sheet-model.test.d.ts +2 -0
  150. package/dist/types/src/model/sheet-model.test.d.ts.map +1 -0
  151. package/dist/types/src/sanity.test.d.ts +2 -0
  152. package/dist/types/src/sanity.test.d.ts.map +1 -0
  153. package/dist/types/src/testing/index.d.ts +2 -0
  154. package/dist/types/src/testing/index.d.ts.map +1 -0
  155. package/dist/types/src/testing/testing.d.ts +8 -0
  156. package/dist/types/src/testing/testing.d.ts.map +1 -0
  157. package/dist/types/src/types.d.ts +15 -4
  158. package/dist/types/src/types.d.ts.map +1 -1
  159. package/dist/vendor/hyperformula.mjs +37145 -0
  160. package/package.json +48 -44
  161. package/src/SheetPlugin.tsx +46 -62
  162. package/src/components/CellEditor/CellEditor.stories.tsx +6 -6
  163. package/src/components/CellEditor/CellEditor.tsx +59 -9
  164. package/src/components/CellEditor/extension.test.ts +3 -4
  165. package/src/components/CellEditor/extension.ts +5 -6
  166. package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +20 -0
  167. package/src/components/ComputeGraph/index.ts +1 -3
  168. package/src/components/GridSheet/GridSheet.stories.tsx +36 -0
  169. package/src/components/GridSheet/GridSheet.tsx +171 -0
  170. package/src/components/GridSheet/util.ts +148 -0
  171. package/src/components/Sheet/Sheet.stories.tsx +48 -88
  172. package/src/components/Sheet/Sheet.tsx +42 -24
  173. package/src/components/Sheet/grid.ts +3 -3
  174. package/src/components/Sheet/nav.ts +19 -19
  175. package/src/components/Sheet/sheet-context.tsx +12 -82
  176. package/src/components/Sheet/threads.tsx +10 -6
  177. package/src/components/SheetContainer.tsx +13 -15
  178. package/src/components/Toolbar/Toolbar.tsx +1 -2
  179. package/src/components/index.ts +1 -0
  180. package/src/defs/index.ts +6 -0
  181. package/src/{model → defs}/types.test.ts +7 -7
  182. package/src/{model → defs}/types.ts +24 -14
  183. package/src/{model → defs}/util.ts +65 -17
  184. package/src/extensions/compute.stories.tsx +151 -0
  185. package/src/extensions/compute.ts +147 -0
  186. package/src/extensions/index.ts +5 -0
  187. package/src/graph/compute-graph-registry.ts +90 -0
  188. package/src/graph/compute-graph.stories.tsx +93 -0
  189. package/src/graph/compute-graph.test.ts +87 -0
  190. package/src/graph/compute-graph.ts +242 -0
  191. package/src/graph/compute-node.ts +63 -0
  192. package/src/{components/ComputeGraph → graph/functions}/async-function.ts +25 -15
  193. package/src/{components/ComputeGraph → graph/functions}/edge-function.ts +16 -14
  194. package/src/graph/functions/index.ts +7 -0
  195. package/src/graph/hyperformula.test.ts +14 -0
  196. package/src/graph/index.ts +8 -0
  197. package/src/graph/testing/index.ts +6 -0
  198. package/src/graph/testing/test-builder.ts +54 -0
  199. package/src/{components/ComputeGraph/custom.ts → graph/testing/test-plugin.ts} +44 -14
  200. package/src/graph/util.ts +8 -0
  201. package/src/hooks/hooks.stories.tsx +50 -0
  202. package/src/hooks/index.ts +7 -0
  203. package/src/hooks/useComputeGraph.ts +28 -0
  204. package/src/hooks/useFormattingModel.ts +11 -0
  205. package/src/hooks/useSheetModel.ts +40 -0
  206. package/src/meta.tsx +1 -5
  207. package/src/{components/Sheet/formatting.ts → model/formatting-model.ts} +20 -13
  208. package/src/model/index.ts +2 -4
  209. package/src/model/sheet-model.test.ts +57 -0
  210. package/src/model/{model.ts → sheet-model.ts} +88 -188
  211. package/src/sanity.test.ts +40 -0
  212. package/src/testing/index.ts +5 -0
  213. package/src/testing/testing.tsx +68 -0
  214. package/src/types.ts +19 -17
  215. package/dist/lib/browser/SheetContainer-Y7ZMFBAP.mjs.map +0 -7
  216. package/dist/lib/browser/chunk-GNNVBNCX.mjs.map +0 -7
  217. package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +0 -7
  218. package/dist/lib/browser/chunk-PGKZPKUD.mjs +0 -175
  219. package/dist/lib/browser/chunk-PGKZPKUD.mjs.map +0 -7
  220. package/dist/lib/browser/chunk-VBF7YENS.mjs +0 -8
  221. package/dist/lib/browser/chunk-VBF7YENS.mjs.map +0 -7
  222. package/dist/lib/browser/chunk-WUPTZUTX.mjs.map +0 -7
  223. package/dist/lib/browser/testing.mjs +0 -92
  224. package/dist/lib/browser/testing.mjs.map +0 -7
  225. package/dist/lib/node/SheetContainer-KEOKUKAQ.cjs.map +0 -7
  226. package/dist/lib/node/chunk-57PB2HPY.cjs +0 -40
  227. package/dist/lib/node/chunk-57PB2HPY.cjs.map +0 -7
  228. package/dist/lib/node/chunk-6LWBQAQZ.cjs +0 -202
  229. package/dist/lib/node/chunk-6LWBQAQZ.cjs.map +0 -7
  230. package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +0 -7
  231. package/dist/lib/node/chunk-VJU3NPUJ.cjs.map +0 -7
  232. package/dist/lib/node/chunk-ZRQZFV5T.cjs.map +0 -7
  233. package/dist/lib/node/testing.cjs +0 -111
  234. package/dist/lib/node/testing.cjs.map +0 -7
  235. package/dist/lib/node-esm/SheetContainer-Y7ZMFBAP.mjs.map +0 -7
  236. package/dist/lib/node-esm/chunk-GNNVBNCX.mjs.map +0 -7
  237. package/dist/lib/node-esm/chunk-JRL5LGCE.mjs.map +0 -7
  238. package/dist/lib/node-esm/chunk-PGKZPKUD.mjs +0 -175
  239. package/dist/lib/node-esm/chunk-PGKZPKUD.mjs.map +0 -7
  240. package/dist/lib/node-esm/chunk-VBF7YENS.mjs +0 -8
  241. package/dist/lib/node-esm/chunk-VBF7YENS.mjs.map +0 -7
  242. package/dist/lib/node-esm/chunk-WUPTZUTX.mjs.map +0 -7
  243. package/dist/lib/node-esm/testing.mjs +0 -92
  244. package/dist/lib/node-esm/testing.mjs.map +0 -7
  245. package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +0 -1
  246. package/dist/types/src/components/ComputeGraph/custom.d.ts +0 -21
  247. package/dist/types/src/components/ComputeGraph/custom.d.ts.map +0 -1
  248. package/dist/types/src/components/ComputeGraph/edge-function.d.ts +0 -20
  249. package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +0 -1
  250. package/dist/types/src/components/ComputeGraph/graph-context.d.ts +0 -12
  251. package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +0 -1
  252. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +0 -2
  253. package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +0 -1
  254. package/dist/types/src/components/ComputeGraph/graph.d.ts +0 -26
  255. package/dist/types/src/components/ComputeGraph/graph.d.ts.map +0 -1
  256. package/dist/types/src/components/Sheet/formatting.d.ts +0 -14
  257. package/dist/types/src/components/Sheet/formatting.d.ts.map +0 -1
  258. package/dist/types/src/model/functions.d.ts.map +0 -1
  259. package/dist/types/src/model/model.browser.test.d.ts +0 -2
  260. package/dist/types/src/model/model.browser.test.d.ts.map +0 -1
  261. package/dist/types/src/model/model.d.ts.map +0 -1
  262. package/dist/types/src/model/types.d.ts.map +0 -1
  263. package/dist/types/src/model/types.test.d.ts.map +0 -1
  264. package/dist/types/src/model/util.d.ts.map +0 -1
  265. package/dist/types/src/testing.d.ts +0 -9
  266. package/dist/types/src/testing.d.ts.map +0 -1
  267. package/src/components/ComputeGraph/graph-context.tsx +0 -50
  268. package/src/components/ComputeGraph/graph.browser.test.ts +0 -49
  269. package/src/components/ComputeGraph/graph.ts +0 -62
  270. package/src/model/model.browser.test.ts +0 -99
  271. package/src/testing.ts +0 -50
  272. /package/dist/types/src/{model → defs}/types.test.d.ts +0 -0
  273. /package/src/{model/functions.ts → graph/functions/function-defs.ts} +0 -0
@@ -2,40 +2,30 @@
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';
11
+ import { getTypename } from '@dxos/echo-schema';
13
12
  import { invariant } from '@dxos/invariant';
14
13
  import { PublicKey } from '@dxos/keys';
15
14
  import { log } from '@dxos/log';
16
- import { type FunctionType } from '@dxos/plugin-script/types';
17
15
 
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';
16
+ import { DetailedCellError, ExportedCellChange } from '#hyperformula';
17
+ import {
18
+ addressFromA1Notation,
19
+ addressToA1Notation,
20
+ type CellAddress,
21
+ type CellRange,
22
+ MAX_COLUMNS,
23
+ MAX_ROWS,
24
+ } from '../defs';
25
+ import { addressFromIndex, addressToIndex, initialize, insertIndices, ReadonlyException } from '../defs';
26
+ import { type ComputeNode, type ComputeGraph, createSheetName, type ComputeNodeEvent } from '../graph';
22
27
  import { type CellScalarValue, type CellValue, type SheetType, ValueTypeEnum } from '../types';
23
28
 
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
29
  const typeMap: Record<string, ValueTypeEnum> = {
40
30
  BOOLEAN: ValueTypeEnum.Boolean,
41
31
  NUMBER_RAW: ValueTypeEnum.Number,
@@ -46,22 +36,15 @@ const typeMap: Record<string, ValueTypeEnum> = {
46
36
  NUMBER_TIME: ValueTypeEnum.Time,
47
37
  };
48
38
 
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) => {
39
+ const getTopLeft = (range: CellRange): CellAddress => {
57
40
  const to = range.to ?? range.from;
58
- return { row: Math.min(range.from.row, to.row), column: Math.min(range.from.column, to.column) };
41
+ return { row: Math.min(range.from.row, to.row), col: Math.min(range.from.col, to.col) };
59
42
  };
60
43
 
61
44
  const toSimpleCellAddress = (sheet: number, cell: CellAddress): SimpleCellAddress => ({
62
45
  sheet,
63
46
  row: cell.row,
64
- col: cell.column,
47
+ col: cell.col,
65
48
  });
66
49
 
67
50
  const toModelRange = (sheet: number, range: CellRange): SimpleCellRange => ({
@@ -69,39 +52,30 @@ const toModelRange = (sheet: number, range: CellRange): SimpleCellRange => ({
69
52
  end: toSimpleCellAddress(sheet, range.to ?? range.from),
70
53
  });
71
54
 
55
+ export type SheetModelOptions = {
56
+ readonly?: boolean;
57
+ };
58
+
72
59
  /**
73
60
  * Spreadsheet data model.
74
61
  *
75
62
  * [ComputeGraphContext] > [SheetContext]:[SheetModel] > [Sheet.Root]
76
63
  */
77
- export class SheetModel {
64
+ // TODO(burdon): Factor out commonality with ComputeNode. Factor out HF.
65
+ export class SheetModel extends Resource {
78
66
  public readonly id = `model-${PublicKey.random().truncate()}`;
79
- private _ctx?: Context = undefined;
80
67
 
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[] = [];
68
+ // Wraps compute node.
69
+ public readonly update = new Event<ComputeNodeEvent>();
88
70
 
89
- public readonly update = new Event();
71
+ private _node?: ComputeNode;
90
72
 
91
73
  constructor(
92
74
  private readonly _graph: ComputeGraph,
93
75
  private readonly _sheet: SheetType,
94
- private readonly _space?: Space,
95
- options: Partial<SheetModelOptions> = {},
76
+ private readonly _options: SheetModelOptions = {},
96
77
  ) {
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 };
104
- this.reset();
78
+ super();
105
79
  }
106
80
 
107
81
  get graph() {
@@ -123,59 +97,22 @@ export class SheetModel {
123
97
  };
124
98
  }
125
99
 
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
100
  /**
139
101
  * Initialize sheet and engine.
140
102
  */
141
- async initialize() {
103
+ protected override async _open() {
142
104
  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
- }
151
- this.reset();
105
+ initialize(this._sheet);
106
+
107
+ // TODO(burdon): SheetModel should extend ComputeNode and be constructed via the graph.
108
+ this._node = this._graph.getOrCreateNode(createSheetName({ type: getTypename(this._sheet)!, id: this._sheet.id }));
109
+ await this._node.open();
152
110
 
153
111
  // Listen for model updates (e.g., async calculations).
154
- const unsubscribe = this._graph.update.on(() => this.update.emit());
112
+ const unsubscribe = this._node.update.on((event) => this.update.emit(event));
155
113
  this._ctx.onDispose(unsubscribe);
156
114
 
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
- }
115
+ this.reset();
179
116
  }
180
117
 
181
118
  /**
@@ -184,14 +121,18 @@ export class SheetModel {
184
121
  * @deprecated
185
122
  */
186
123
  reset() {
187
- this._graph.hf.clearSheet(this._sheetId);
124
+ invariant(this._node);
125
+ this._node.graph.hf.clearSheet(this._node.sheetId);
188
126
  Object.entries(this._sheet.cells).forEach(([key, { value }]) => {
189
- const { column, row } = addressFromIndex(this._sheet, key);
127
+ invariant(this._node);
128
+ const { col, row } = addressFromIndex(this._sheet, key);
190
129
  if (typeof value === 'string' && value.charAt(0) === '=') {
191
- value = this.mapFormulaBindingToFormula(this.mapFormulaBindingFromId(this.mapFormulaIndicesToRefs(value)));
130
+ value = this._graph.mapFormulaToNative(
131
+ this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value)),
132
+ );
192
133
  }
193
134
 
194
- this._graph.hf.setCellContents({ sheet: this._sheetId, row, col: column }, value);
135
+ this._node.graph.hf.setCellContents({ sheet: this._node.sheetId, row, col }, value);
195
136
  });
196
137
  }
197
138
 
@@ -203,16 +144,16 @@ export class SheetModel {
203
144
  */
204
145
  // TODO(burdon): Remove.
205
146
  recalculate() {
206
- this._graph.hf.rebuildAndRecalculate();
147
+ this._node?.graph.hf.rebuildAndRecalculate();
207
148
  }
208
149
 
209
150
  insertRows(i: number, n = 1) {
210
- this._insertIndices(this._sheet.rows, i, n, DEFAULT_ROWS);
151
+ insertIndices(this._sheet.rows, i, n, MAX_ROWS);
211
152
  this.reset();
212
153
  }
213
154
 
214
155
  insertColumns(i: number, n = 1) {
215
- this._insertIndices(this._sheet.columns, i, n, DEFAULT_COLUMNS);
156
+ insertIndices(this._sheet.columns, i, n, MAX_COLUMNS);
216
157
  this.reset();
217
158
  }
218
159
 
@@ -220,13 +161,15 @@ export class SheetModel {
220
161
  // Undoable actions.
221
162
  // TODO(burdon): Group undoable methods; consistently update hf/sheet.
222
163
  //
164
+
223
165
  /**
224
166
  * Clear range of values.
225
167
  */
226
168
  clear(range: CellRange) {
169
+ invariant(this._node);
227
170
  const topLeft = getTopLeft(range);
228
171
  const values = this._iterRange(range, () => null);
229
- this._graph.hf.setCellContents(toSimpleCellAddress(this._sheetId, topLeft), values);
172
+ this._node.graph.hf.setCellContents(toSimpleCellAddress(this._node.sheetId, topLeft), values);
230
173
  this._iterRange(range, (cell) => {
231
174
  const idx = addressToIndex(this._sheet, cell);
232
175
  delete this._sheet.cells[idx];
@@ -234,7 +177,8 @@ export class SheetModel {
234
177
  }
235
178
 
236
179
  cut(range: CellRange) {
237
- this._graph.hf.cut(toModelRange(this._sheetId, range));
180
+ invariant(this._node);
181
+ this._node.graph.hf.cut(toModelRange(this._node.sheetId, range));
238
182
  this._iterRange(range, (cell) => {
239
183
  const idx = addressToIndex(this._sheet, cell);
240
184
  delete this._sheet.cells[idx];
@@ -242,16 +186,18 @@ export class SheetModel {
242
186
  }
243
187
 
244
188
  copy(range: CellRange) {
245
- this._graph.hf.copy(toModelRange(this._sheetId, range));
189
+ invariant(this._node);
190
+ this._node.graph.hf.copy(toModelRange(this._node.sheetId, range));
246
191
  }
247
192
 
248
193
  paste(cell: CellAddress) {
249
- if (!this._graph.hf.isClipboardEmpty()) {
250
- const changes = this._graph.hf.paste(toSimpleCellAddress(this._sheetId, cell));
194
+ invariant(this._node);
195
+ if (!this._node.graph.hf.isClipboardEmpty()) {
196
+ const changes = this._node.graph.hf.paste(toSimpleCellAddress(this._node.sheetId, cell));
251
197
  for (const change of changes) {
252
198
  if (change instanceof ExportedCellChange) {
253
199
  const { address, newValue } = change;
254
- const idx = addressToIndex(this._sheet, { row: address.row, column: address.col });
200
+ const idx = addressToIndex(this._sheet, { row: address.row, col: address.col });
255
201
  this._sheet.cells[idx] = { value: newValue };
256
202
  }
257
203
  }
@@ -260,16 +206,18 @@ export class SheetModel {
260
206
 
261
207
  // TODO(burdon): Display undo/redo state.
262
208
  undo() {
263
- if (this._graph.hf.isThereSomethingToUndo()) {
264
- this._graph.hf.undo();
265
- this.update.emit();
209
+ invariant(this._node);
210
+ if (this._node.graph.hf.isThereSomethingToUndo()) {
211
+ this._node.graph.hf.undo();
212
+ // this.update.emit();
266
213
  }
267
214
  }
268
215
 
269
216
  redo() {
270
- if (this._graph.hf.isThereSomethingToRedo()) {
271
- this._graph.hf.redo();
272
- this.update.emit();
217
+ invariant(this._node);
218
+ if (this._node.graph.hf.isThereSomethingToRedo()) {
219
+ this._node.graph.hf.redo();
220
+ // this.update.emit();
273
221
  }
274
222
  }
275
223
 
@@ -291,7 +239,7 @@ export class SheetModel {
291
239
  }
292
240
 
293
241
  if (typeof value === 'string' && value.charAt(0) === '=') {
294
- return this.mapFormulaBindingFromId(this.mapFormulaIndicesToRefs(value));
242
+ return this._graph.mapFunctionBindingFromId(this.mapFormulaIndicesToRefs(value));
295
243
  } else {
296
244
  return String(value);
297
245
  }
@@ -309,7 +257,8 @@ export class SheetModel {
309
257
  */
310
258
  getValue(cell: CellAddress): CellScalarValue {
311
259
  // Applies rounding and post-processing.
312
- const value = this._graph.hf.getCellValue(toSimpleCellAddress(this._sheetId, cell));
260
+ invariant(this._node);
261
+ const value = this._node.graph.hf.getCellValue(toSimpleCellAddress(this._node.sheetId, cell));
313
262
  if (value instanceof DetailedCellError) {
314
263
  return value.toString();
315
264
  }
@@ -321,8 +270,9 @@ export class SheetModel {
321
270
  * Get value type.
322
271
  */
323
272
  getValueType(cell: CellAddress): ValueTypeEnum {
324
- const addr = toSimpleCellAddress(this._sheetId, cell);
325
- const type = this._graph.hf.getCellValueDetailedType(addr);
273
+ invariant(this._node);
274
+ const addr = toSimpleCellAddress(this._node.sheetId, cell);
275
+ const type = this._node.graph.hf.getCellValueDetailedType(addr);
326
276
  return typeMap[type];
327
277
  }
328
278
 
@@ -330,6 +280,7 @@ export class SheetModel {
330
280
  * Sets the value, updating the sheet and engine.
331
281
  */
332
282
  setValue(cell: CellAddress, value: CellScalarValue) {
283
+ invariant(this._node);
333
284
  if (this._options.readonly) {
334
285
  throw new ReadonlyException();
335
286
  }
@@ -337,21 +288,22 @@ export class SheetModel {
337
288
  // Reallocate if > current bounds.
338
289
  let refresh = false;
339
290
  if (cell.row >= this._sheet.rows.length) {
340
- this._insertIndices(this._sheet.rows, cell.row, 1, DEFAULT_ROWS);
291
+ insertIndices(this._sheet.rows, cell.row, 1, MAX_ROWS);
341
292
  refresh = true;
342
293
  }
343
- if (cell.column >= this._sheet.columns.length) {
344
- this._insertIndices(this._sheet.columns, cell.column, 1, DEFAULT_COLUMNS);
294
+ if (cell.col >= this._sheet.columns.length) {
295
+ insertIndices(this._sheet.columns, cell.col, 1, MAX_COLUMNS);
345
296
  refresh = true;
346
297
  }
298
+
347
299
  if (refresh) {
348
300
  // TODO(burdon): Remove.
349
301
  this.reset();
350
302
  }
351
303
 
352
304
  // 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],
305
+ this._node.graph.hf.setCellContents({ sheet: this._node.sheetId, row: cell.row, col: cell.col }, [
306
+ [typeof value === 'string' && value.charAt(0) === '=' ? this._graph.mapFormulaToNative(value) : value],
355
307
  ]);
356
308
 
357
309
  // Insert into sheet.
@@ -360,7 +312,7 @@ export class SheetModel {
360
312
  delete this._sheet.cells[idx];
361
313
  } else {
362
314
  if (typeof value === 'string' && value.charAt(0) === '=') {
363
- value = this.mapFormulaBindingToId(this.mapFormulaRefsToIndices(value));
315
+ value = this._graph.mapFunctionBindingToId(this.mapFormulaRefsToIndices(value));
364
316
  }
365
317
 
366
318
  this._sheet.cells[idx] = { value };
@@ -382,35 +334,23 @@ export class SheetModel {
382
334
  private _iterRange(range: CellRange, cb: (cell: CellAddress) => CellScalarValue | void): CellScalarValue[][] {
383
335
  const to = range.to ?? range.from;
384
336
  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)];
337
+ const columnRange = [Math.min(range.from.col, to.col), Math.max(range.from.col, to.col)];
386
338
  const rows: CellScalarValue[][] = [];
387
339
  for (let row = rowRange[0]; row <= rowRange[1]; row++) {
388
340
  const rowCells: CellScalarValue[] = [];
389
341
  for (let column = columnRange[0]; column <= columnRange[1]; column++) {
390
- const value = cb({ row, column });
342
+ const value = cb({ row, col: column });
391
343
  if (value !== undefined) {
392
344
  rowCells.push(value);
393
345
  }
394
346
  }
347
+
395
348
  rows.push(rowCells);
396
349
  }
397
350
 
398
351
  return rows;
399
352
  }
400
353
 
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
354
  // TODO(burdon): Delete index.
415
355
  private _deleteIndices(indices: string[], i: number, n: number) {
416
356
  throw new Error('Not implemented');
@@ -425,49 +365,6 @@ export class SheetModel {
425
365
  // Indices.
426
366
  //
427
367
 
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
368
  /**
472
369
  * Map from A1 notation to indices.
473
370
  */
@@ -503,14 +400,17 @@ export class SheetModel {
503
400
  }
504
401
 
505
402
  toDateTime(num: number): SimpleDateTime {
506
- return this._graph.hf.numberToDateTime(num) as SimpleDateTime;
403
+ invariant(this._node);
404
+ return this._node.graph.hf.numberToDateTime(num) as SimpleDateTime;
507
405
  }
508
406
 
509
407
  toDate(num: number): SimpleDate {
510
- return this._graph.hf.numberToDate(num) as SimpleDate;
408
+ invariant(this._node);
409
+ return this._node.graph.hf.numberToDate(num) as SimpleDate;
511
410
  }
512
411
 
513
412
  toTime(num: number): SimpleDate {
514
- return this._graph.hf.numberToTime(num) as SimpleDate;
413
+ invariant(this._node);
414
+ return this._node.graph.hf.numberToTime(num) as SimpleDate;
515
415
  }
516
416
  }
@@ -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,68 @@
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, type ComputeGraphOptions, ComputeGraphRegistry } from '../graph';
14
+ import { type CellValue, type CreateSheetOptions } from '../types';
15
+
16
+ const testSheetName = 'test';
17
+
18
+ export const createTestCells = (): Record<string, CellValue> => ({
19
+ B1: { value: 'Qty2' },
20
+ B3: { value: 1 },
21
+ B4: { value: 2 },
22
+ B5: { value: 3 },
23
+ B7: { value: 'Total' },
24
+
25
+ C1: { value: 'Price' },
26
+ C3: { value: 2_000 },
27
+ C4: { value: 2_500 },
28
+ C5: { value: 3_000 },
29
+ C7: { value: '=SUMPRODUCT(B2:B6, C2:C6)' },
30
+ // C8: { value: '=C7*CRYPTO(D7)' },
31
+ C8: { value: '=C7*TEST()' },
32
+
33
+ D7: { value: 'USD' },
34
+ D8: { value: 'BTC' },
35
+
36
+ E3: { value: '=TODAY()' },
37
+ E4: { value: '=NOW()' },
38
+
39
+ F1: { value: `=${testSheetName}!A1` }, // Ref test sheet.
40
+ F3: { value: true },
41
+ F4: { value: false },
42
+ F5: { value: '8%' },
43
+ F6: { value: '$10000' },
44
+ });
45
+
46
+ export const useTestSheet = (space?: Space, graph?: ComputeGraph, options?: CreateSheetOptions) => {
47
+ const [sheet] = useAsyncState(async () => {
48
+ if (!space || !graph) {
49
+ return;
50
+ }
51
+
52
+ const sheet = createSheet(options);
53
+ space.db.add(sheet);
54
+ return sheet;
55
+ }, [space, graph]);
56
+ return sheet;
57
+ };
58
+
59
+ export const withComputeGraphDecorator =
60
+ (options?: ComputeGraphOptions): Decorator =>
61
+ (Story) => {
62
+ const [registry] = useState(new ComputeGraphRegistry(options));
63
+ return (
64
+ <ComputeGraphContextProvider registry={registry}>
65
+ <Story />
66
+ </ComputeGraphContextProvider>
67
+ );
68
+ };