@dxos/plugin-sheet 0.6.13 → 0.6.14-main.7bd9c89
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.
- package/dist/lib/browser/SheetContainer-AKWROARP.mjs +290 -0
- package/dist/lib/browser/SheetContainer-AKWROARP.mjs.map +7 -0
- package/dist/lib/browser/chunk-BWN5DZWZ.mjs +74 -0
- package/dist/lib/browser/chunk-BWN5DZWZ.mjs.map +7 -0
- package/dist/lib/browser/chunk-D3QTX46O.mjs +14 -0
- package/dist/lib/browser/chunk-D3QTX46O.mjs.map +7 -0
- package/dist/lib/browser/chunk-FGMFOW6U.mjs +1570 -0
- package/dist/lib/browser/chunk-FGMFOW6U.mjs.map +7 -0
- package/dist/lib/browser/chunk-GSV5QNLD.mjs +2966 -0
- package/dist/lib/browser/chunk-GSV5QNLD.mjs.map +7 -0
- package/dist/lib/browser/graph-M4IQ76QX.mjs +33 -0
- package/dist/lib/browser/graph-M4IQ76QX.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +93 -62
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +1 -1
- package/dist/lib/browser/types.mjs +6 -12
- package/dist/lib/node/SheetContainer-N5IQGEFL.cjs +300 -0
- package/dist/lib/node/SheetContainer-N5IQGEFL.cjs.map +7 -0
- package/dist/lib/node/chunk-53BMSUIK.cjs +1569 -0
- package/dist/lib/node/chunk-53BMSUIK.cjs.map +7 -0
- package/dist/lib/node/{chunk-5KKJ4NPP.cjs → chunk-5XPK2V4A.cjs} +418 -678
- package/dist/lib/node/chunk-5XPK2V4A.cjs.map +7 -0
- package/dist/lib/node/{chunk-DSYKOI4E.cjs → chunk-NZARD7UP.cjs} +40 -51
- package/dist/lib/node/chunk-NZARD7UP.cjs.map +7 -0
- package/dist/lib/node/chunk-QIFIGEKV.cjs +37 -0
- package/dist/lib/node/chunk-QIFIGEKV.cjs.map +7 -0
- package/dist/lib/node/graph-Q3N2X26H.cjs +55 -0
- package/dist/lib/node/graph-Q3N2X26H.cjs.map +7 -0
- package/dist/lib/node/index.cjs +105 -69
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.cjs +3 -3
- package/dist/lib/node/meta.cjs.map +1 -1
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types.cjs +9 -15
- package/dist/lib/node/types.cjs.map +2 -2
- package/dist/lib/node-esm/SheetContainer-46PBMF2E.mjs +291 -0
- package/dist/lib/node-esm/SheetContainer-46PBMF2E.mjs.map +7 -0
- package/dist/lib/{browser/chunk-D5AGLXJP.mjs → node-esm/chunk-5WPZCXNS.mjs} +411 -678
- package/dist/lib/node-esm/chunk-5WPZCXNS.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-T3PRH7QS.mjs +1571 -0
- package/dist/lib/node-esm/chunk-T3PRH7QS.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-VCYJWE3O.mjs +16 -0
- package/dist/lib/node-esm/chunk-VCYJWE3O.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-WFDTY3IC.mjs +75 -0
- package/dist/lib/node-esm/chunk-WFDTY3IC.mjs.map +7 -0
- package/dist/lib/node-esm/graph-SMPUMOV2.mjs +34 -0
- package/dist/lib/node-esm/graph-SMPUMOV2.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +280 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/meta.mjs +10 -0
- package/dist/lib/node-esm/meta.mjs.map +7 -0
- package/dist/lib/node-esm/types.mjs +17 -0
- package/dist/lib/node-esm/types.mjs.map +7 -0
- package/dist/types/src/SheetPlugin.d.ts.map +1 -1
- package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +11 -0
- package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -0
- package/dist/types/src/components/ComputeGraph/index.d.ts +1 -3
- package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
- package/dist/types/src/components/FunctionEditor/FunctionEditor.d.ts +3 -0
- package/dist/types/src/components/FunctionEditor/FunctionEditor.d.ts.map +1 -0
- package/dist/types/src/components/FunctionEditor/index.d.ts +2 -0
- package/dist/types/src/components/FunctionEditor/index.d.ts.map +1 -0
- package/dist/types/src/components/GridSheet/GridSheet.d.ts +3 -0
- package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -0
- package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +6 -0
- package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -0
- package/dist/types/src/components/{CellEditor/CellEditor.stories.d.ts → GridSheet/SheetCellEditor.stories.d.ts} +5 -9
- package/dist/types/src/components/GridSheet/SheetCellEditor.stories.d.ts.map +1 -0
- package/dist/types/src/components/GridSheet/index.d.ts +2 -0
- package/dist/types/src/components/GridSheet/index.d.ts.map +1 -0
- package/dist/types/src/components/GridSheet/util.d.ts +16 -0
- package/dist/types/src/components/GridSheet/util.d.ts.map +1 -0
- package/dist/types/src/components/SheetContainer/SheetContainer.d.ts +6 -0
- package/dist/types/src/components/SheetContainer/SheetContainer.d.ts.map +1 -0
- package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts +6 -0
- package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts.map +1 -0
- package/dist/types/src/components/SheetContainer/index.d.ts +3 -0
- package/dist/types/src/components/SheetContainer/index.d.ts.map +1 -0
- package/dist/types/src/components/SheetContext/SheetContext.d.ts +26 -0
- package/dist/types/src/components/SheetContext/SheetContext.d.ts.map +1 -0
- package/dist/types/src/components/SheetContext/index.d.ts +2 -0
- package/dist/types/src/components/SheetContext/index.d.ts.map +1 -0
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +33 -9
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +4 -32
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +4 -4
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/defs/index.d.ts +4 -0
- package/dist/types/src/defs/index.d.ts.map +1 -0
- package/dist/types/src/defs/sheet-range-types.d.ts +13 -0
- package/dist/types/src/defs/sheet-range-types.d.ts.map +1 -0
- package/dist/types/src/{model → defs}/types.d.ts +8 -3
- package/dist/types/src/defs/types.d.ts.map +1 -0
- package/dist/types/src/defs/types.test.d.ts.map +1 -0
- package/dist/types/src/defs/util.d.ts +43 -0
- package/dist/types/src/defs/util.d.ts.map +1 -0
- package/dist/types/src/extensions/compute.d.ts +6 -0
- package/dist/types/src/extensions/compute.d.ts.map +1 -0
- package/dist/types/src/extensions/compute.stories.d.ts +21 -0
- package/dist/types/src/extensions/compute.stories.d.ts.map +1 -0
- package/dist/types/src/{components/CellEditor → extensions/editor}/extension.d.ts +1 -1
- package/dist/types/src/extensions/editor/extension.d.ts.map +1 -0
- package/dist/types/src/extensions/editor/extension.test.d.ts.map +1 -0
- package/dist/types/src/extensions/editor/index.d.ts +2 -0
- package/dist/types/src/extensions/editor/index.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +3 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -0
- package/dist/types/src/graph/compute-graph-registry.d.ts +34 -0
- package/dist/types/src/graph/compute-graph-registry.d.ts.map +1 -0
- package/dist/types/src/graph/compute-graph.d.ts +64 -0
- package/dist/types/src/graph/compute-graph.d.ts.map +1 -0
- package/dist/types/src/graph/compute-graph.stories.d.ts +6 -0
- package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -0
- package/dist/types/src/graph/compute-graph.test.d.ts +2 -0
- package/dist/types/src/graph/compute-graph.test.d.ts.map +1 -0
- package/dist/types/src/graph/compute-node.d.ts +26 -0
- package/dist/types/src/graph/compute-node.d.ts.map +1 -0
- package/dist/types/src/{components/ComputeGraph → graph/functions}/async-function.d.ts +14 -5
- package/dist/types/src/graph/functions/async-function.d.ts.map +1 -0
- package/dist/types/src/graph/functions/edge-function.d.ts +21 -0
- package/dist/types/src/graph/functions/edge-function.d.ts.map +1 -0
- package/dist/types/src/{model/functions.d.ts → graph/functions/function-defs.d.ts} +1 -1
- package/dist/types/src/graph/functions/function-defs.d.ts.map +1 -0
- package/dist/types/src/graph/functions/index.d.ts +4 -0
- package/dist/types/src/graph/functions/index.d.ts.map +1 -0
- package/dist/types/src/graph/hyperformula.test.d.ts +2 -0
- package/dist/types/src/graph/hyperformula.test.d.ts.map +1 -0
- package/dist/types/src/graph/index.d.ts +5 -0
- package/dist/types/src/graph/index.d.ts.map +1 -0
- package/dist/types/src/graph/testing/index.d.ts +3 -0
- package/dist/types/src/graph/testing/index.d.ts.map +1 -0
- package/dist/types/src/graph/testing/test-builder.d.ts +15 -0
- package/dist/types/src/graph/testing/test-builder.d.ts.map +1 -0
- package/dist/types/src/graph/testing/test-plugin.d.ts +36 -0
- package/dist/types/src/graph/testing/test-plugin.d.ts.map +1 -0
- package/dist/types/src/graph/util.d.ts +2 -0
- package/dist/types/src/graph/util.d.ts.map +1 -0
- package/dist/types/src/hooks/hooks.stories.d.ts +6 -0
- package/dist/types/src/hooks/hooks.stories.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +4 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/threads.d.ts +8 -0
- package/dist/types/src/hooks/threads.d.ts.map +1 -0
- package/dist/types/src/hooks/useComputeGraph.d.ts +7 -0
- package/dist/types/src/hooks/useComputeGraph.d.ts.map +1 -0
- package/dist/types/src/hooks/useSheetModel.d.ts +8 -0
- package/dist/types/src/hooks/useSheetModel.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +3 -9
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/model/decorations.d.ts +26 -0
- package/dist/types/src/model/decorations.d.ts.map +1 -0
- package/dist/types/src/model/index.d.ts +2 -3
- package/dist/types/src/model/index.d.ts.map +1 -1
- package/dist/types/src/model/{model.d.ts → sheet-model.d.ts} +13 -67
- package/dist/types/src/model/sheet-model.d.ts.map +1 -0
- package/dist/types/src/model/sheet-model.test.d.ts +2 -0
- package/dist/types/src/model/sheet-model.test.d.ts.map +1 -0
- package/dist/types/src/sanity.test.d.ts +2 -0
- package/dist/types/src/sanity.test.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/testing.d.ts +8 -0
- package/dist/types/src/testing/testing.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +17 -12
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +125 -40
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/vendor/hyperformula.mjs +37145 -0
- package/package.json +58 -52
- package/src/SheetPlugin.tsx +52 -74
- package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +20 -0
- package/src/components/ComputeGraph/index.ts +1 -3
- package/src/components/FunctionEditor/FunctionEditor.tsx +45 -0
- package/src/components/FunctionEditor/index.ts +5 -0
- package/src/components/GridSheet/GridSheet.stories.tsx +44 -0
- package/src/components/GridSheet/GridSheet.tsx +201 -0
- package/src/components/{CellEditor/CellEditor.stories.tsx → GridSheet/SheetCellEditor.stories.tsx} +18 -15
- package/src/components/GridSheet/index.ts +5 -0
- package/src/components/GridSheet/util.ts +154 -0
- package/src/components/SheetContainer/SheetContainer.stories.tsx +43 -0
- package/src/components/SheetContainer/SheetContainer.tsx +27 -0
- package/src/components/SheetContainer/index.ts +7 -0
- package/src/components/SheetContext/SheetContext.tsx +104 -0
- package/src/components/SheetContext/index.ts +5 -0
- package/src/components/Toolbar/Toolbar.stories.tsx +9 -6
- package/src/components/Toolbar/Toolbar.tsx +242 -112
- package/src/components/index.ts +4 -3
- package/src/defs/index.ts +7 -0
- package/src/defs/sheet-range-types.ts +46 -0
- package/src/{model → defs}/types.test.ts +8 -9
- package/src/{model → defs}/types.ts +24 -14
- package/src/defs/util.ts +151 -0
- package/src/extensions/compute.stories.tsx +155 -0
- package/src/extensions/compute.ts +147 -0
- package/src/{components/CellEditor → extensions/editor}/extension.test.ts +4 -6
- package/src/{components/CellEditor → extensions/editor}/extension.ts +5 -6
- package/src/{components/CellEditor → extensions/editor}/index.ts +0 -1
- package/src/extensions/index.ts +6 -0
- package/src/graph/compute-graph-registry.ts +90 -0
- package/src/graph/compute-graph.stories.tsx +96 -0
- package/src/graph/compute-graph.test.ts +87 -0
- package/src/graph/compute-graph.ts +242 -0
- package/src/graph/compute-node.ts +63 -0
- package/src/{components/ComputeGraph → graph/functions}/async-function.ts +25 -15
- package/src/{components/ComputeGraph → graph/functions}/edge-function.ts +16 -14
- package/src/graph/functions/index.ts +7 -0
- package/src/graph/hyperformula.test.ts +14 -0
- package/src/graph/index.ts +8 -0
- package/src/graph/testing/index.ts +6 -0
- package/src/graph/testing/test-builder.ts +54 -0
- package/src/{components/ComputeGraph/custom.ts → graph/testing/test-plugin.ts} +44 -14
- package/src/graph/util.ts +8 -0
- package/src/hooks/hooks.stories.tsx +53 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/threads.ts +147 -0
- package/src/hooks/useComputeGraph.ts +28 -0
- package/src/hooks/useSheetModel.ts +40 -0
- package/src/meta.ts +14 -0
- package/src/model/decorations.ts +66 -0
- package/src/model/index.ts +2 -3
- package/src/model/sheet-model.test.ts +57 -0
- package/src/model/sheet-model.ts +418 -0
- package/src/sanity.test.ts +40 -0
- package/src/{components/Sheet → testing}/index.ts +1 -1
- package/src/testing/testing.tsx +68 -0
- package/src/translations.ts +6 -1
- package/src/types.ts +40 -47
- package/dist/lib/browser/SheetContainer-U4H5D34A.mjs +0 -1772
- package/dist/lib/browser/SheetContainer-U4H5D34A.mjs.map +0 -7
- package/dist/lib/browser/chunk-APHOLYUB.mjs +0 -175
- package/dist/lib/browser/chunk-APHOLYUB.mjs.map +0 -7
- package/dist/lib/browser/chunk-D5AGLXJP.mjs.map +0 -7
- package/dist/lib/browser/chunk-FUAGSXA4.mjs +0 -82
- package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +0 -7
- package/dist/lib/browser/chunk-JRL5LGCE.mjs +0 -18
- package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +0 -7
- package/dist/lib/browser/chunk-NU4PBN33.mjs +0 -8
- package/dist/lib/browser/chunk-NU4PBN33.mjs.map +0 -7
- package/dist/lib/browser/testing.mjs +0 -92
- package/dist/lib/browser/testing.mjs.map +0 -7
- package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs +0 -1765
- package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs.map +0 -7
- package/dist/lib/node/chunk-5KKJ4NPP.cjs.map +0 -7
- package/dist/lib/node/chunk-BJ6ZD7MN.cjs +0 -51
- package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +0 -7
- package/dist/lib/node/chunk-CN3RPESU.cjs +0 -202
- package/dist/lib/node/chunk-CN3RPESU.cjs.map +0 -7
- package/dist/lib/node/chunk-DSYKOI4E.cjs.map +0 -7
- package/dist/lib/node/chunk-PYXHNAAK.cjs +0 -40
- package/dist/lib/node/chunk-PYXHNAAK.cjs.map +0 -7
- package/dist/lib/node/testing.cjs +0 -111
- package/dist/lib/node/testing.cjs.map +0 -7
- package/dist/types/src/components/CellEditor/CellEditor.d.ts +0 -14
- package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +0 -1
- package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +0 -1
- package/dist/types/src/components/CellEditor/extension.d.ts.map +0 -1
- package/dist/types/src/components/CellEditor/extension.test.d.ts.map +0 -1
- package/dist/types/src/components/CellEditor/index.d.ts +0 -3
- package/dist/types/src/components/CellEditor/index.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/custom.d.ts +0 -21
- package/dist/types/src/components/ComputeGraph/custom.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/edge-function.d.ts +0 -20
- package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/graph-context.d.ts +0 -12
- package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +0 -2
- package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/graph.d.ts +0 -26
- package/dist/types/src/components/ComputeGraph/graph.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/Sheet.d.ts +0 -55
- package/dist/types/src/components/Sheet/Sheet.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/Sheet.stories.d.ts +0 -54
- package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/formatting.d.ts +0 -14
- package/dist/types/src/components/Sheet/formatting.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/grid.d.ts +0 -52
- package/dist/types/src/components/Sheet/grid.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/index.d.ts +0 -2
- package/dist/types/src/components/Sheet/index.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/nav.d.ts +0 -29
- package/dist/types/src/components/Sheet/nav.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/sheet-context.d.ts +0 -25
- package/dist/types/src/components/Sheet/sheet-context.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/util.d.ts +0 -18
- package/dist/types/src/components/Sheet/util.d.ts.map +0 -1
- package/dist/types/src/components/SheetContainer.d.ts +0 -9
- package/dist/types/src/components/SheetContainer.d.ts.map +0 -1
- package/dist/types/src/components/Toolbar/common.d.ts +0 -20
- package/dist/types/src/components/Toolbar/common.d.ts.map +0 -1
- package/dist/types/src/model/functions.d.ts.map +0 -1
- package/dist/types/src/model/model.browser.test.d.ts +0 -2
- package/dist/types/src/model/model.browser.test.d.ts.map +0 -1
- package/dist/types/src/model/model.d.ts.map +0 -1
- package/dist/types/src/model/types.d.ts.map +0 -1
- package/dist/types/src/model/types.test.d.ts.map +0 -1
- package/dist/types/src/model/util.d.ts +0 -15
- package/dist/types/src/model/util.d.ts.map +0 -1
- package/dist/types/src/testing.d.ts +0 -9
- package/dist/types/src/testing.d.ts.map +0 -1
- package/src/components/CellEditor/CellEditor.tsx +0 -113
- package/src/components/ComputeGraph/graph-context.tsx +0 -50
- package/src/components/ComputeGraph/graph.browser.test.ts +0 -50
- package/src/components/ComputeGraph/graph.ts +0 -62
- package/src/components/Sheet/Sheet.stories.tsx +0 -287
- package/src/components/Sheet/Sheet.tsx +0 -1160
- package/src/components/Sheet/formatting.ts +0 -106
- package/src/components/Sheet/grid.ts +0 -191
- package/src/components/Sheet/nav.ts +0 -157
- package/src/components/Sheet/sheet-context.tsx +0 -150
- package/src/components/Sheet/util.ts +0 -56
- package/src/components/SheetContainer.tsx +0 -34
- package/src/components/Toolbar/common.tsx +0 -72
- package/src/meta.tsx +0 -18
- package/src/model/model.browser.test.ts +0 -100
- package/src/model/model.ts +0 -550
- package/src/model/util.ts +0 -36
- package/src/testing.ts +0 -50
- /package/dist/types/src/{model → defs}/types.test.d.ts +0 -0
- /package/dist/types/src/{components/CellEditor → extensions/editor}/extension.test.d.ts +0 -0
- /package/src/{model/functions.ts → graph/functions/function-defs.ts} +0 -0
package/src/defs/util.ts
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
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
|
+
ranges: [],
|
|
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
|
+
};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2023 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import '@dxos-theme';
|
|
6
|
+
|
|
7
|
+
import { type Meta } from '@storybook/react';
|
|
8
|
+
import React, { useEffect, useMemo } from 'react';
|
|
9
|
+
|
|
10
|
+
import { PublicKey } from '@dxos/keys';
|
|
11
|
+
import { useSpace } from '@dxos/react-client/echo';
|
|
12
|
+
import { withClientProvider } from '@dxos/react-client/testing';
|
|
13
|
+
import { useThemeContext } from '@dxos/react-ui';
|
|
14
|
+
import {
|
|
15
|
+
createBasicExtensions,
|
|
16
|
+
createMarkdownExtensions,
|
|
17
|
+
createThemeExtensions,
|
|
18
|
+
decorateMarkdown,
|
|
19
|
+
documentId,
|
|
20
|
+
useTextEditor,
|
|
21
|
+
} from '@dxos/react-ui-editor';
|
|
22
|
+
import { withTheme, withLayout } from '@dxos/storybook-utils';
|
|
23
|
+
import { nonNullable } from '@dxos/util';
|
|
24
|
+
|
|
25
|
+
import { compute, computeGraphFacet } from './compute';
|
|
26
|
+
import { GridSheet, SheetProvider } from '../components';
|
|
27
|
+
import { useComputeGraph, useSheetModel } from '../hooks';
|
|
28
|
+
import { useTestSheet, withComputeGraphDecorator } from '../testing';
|
|
29
|
+
import { SheetType } from '../types';
|
|
30
|
+
|
|
31
|
+
const str = (...lines: string[]) => lines.join('\n');
|
|
32
|
+
|
|
33
|
+
type EditorProps = {
|
|
34
|
+
text?: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// TODO(burdon): Implement named expressions.
|
|
38
|
+
// https://hyperformula.handsontable.com/guide/cell-references.html
|
|
39
|
+
|
|
40
|
+
// TODO(burdon): Inline Adobe eCharts.
|
|
41
|
+
|
|
42
|
+
const SHEET_NAME = 'Test Sheet';
|
|
43
|
+
|
|
44
|
+
const EditorStory = ({ text }: EditorProps) => {
|
|
45
|
+
const id = useMemo(() => PublicKey.random(), []);
|
|
46
|
+
const { themeMode } = useThemeContext();
|
|
47
|
+
const space = useSpace();
|
|
48
|
+
const computeGraph = useComputeGraph(space);
|
|
49
|
+
const { parentRef, focusAttributes } = useTextEditor(
|
|
50
|
+
() => ({
|
|
51
|
+
initialValue: text,
|
|
52
|
+
extensions: [
|
|
53
|
+
createBasicExtensions(),
|
|
54
|
+
createMarkdownExtensions({ themeMode }),
|
|
55
|
+
createThemeExtensions({ themeMode, syntaxHighlighting: true }),
|
|
56
|
+
documentId.of(id.toHex()),
|
|
57
|
+
computeGraph && computeGraphFacet.of(computeGraph),
|
|
58
|
+
compute(),
|
|
59
|
+
decorateMarkdown(),
|
|
60
|
+
].filter(nonNullable),
|
|
61
|
+
}),
|
|
62
|
+
[computeGraph, 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
|
+
<SheetProvider graph={graph} sheet={sheet}>
|
|
86
|
+
<GridSheet />
|
|
87
|
+
</SheetProvider>
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const GraphStory = (props: EditorProps) => {
|
|
93
|
+
return (
|
|
94
|
+
<div className='grid grid-rows-2'>
|
|
95
|
+
<EditorStory {...props} />
|
|
96
|
+
<Grid />
|
|
97
|
+
</div>
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// TODO(burdon): Inline formulae.
|
|
102
|
+
export const Default = {
|
|
103
|
+
render: EditorStory,
|
|
104
|
+
args: {
|
|
105
|
+
text: str(
|
|
106
|
+
//
|
|
107
|
+
'# Compute Graph',
|
|
108
|
+
'',
|
|
109
|
+
'This is a compute expression:',
|
|
110
|
+
'',
|
|
111
|
+
'```dx',
|
|
112
|
+
'=SUM(1, 2)',
|
|
113
|
+
'```',
|
|
114
|
+
'',
|
|
115
|
+
'It should change in realtime.',
|
|
116
|
+
'',
|
|
117
|
+
'```dx',
|
|
118
|
+
'=SUM(3, 5)',
|
|
119
|
+
'```',
|
|
120
|
+
'',
|
|
121
|
+
'',
|
|
122
|
+
),
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const Graph = {
|
|
127
|
+
render: GraphStory,
|
|
128
|
+
args: {
|
|
129
|
+
text: str(
|
|
130
|
+
//
|
|
131
|
+
'# Compute Graph',
|
|
132
|
+
'',
|
|
133
|
+
'The total projected cost is:',
|
|
134
|
+
'',
|
|
135
|
+
'```dx',
|
|
136
|
+
`="${SHEET_NAME}"!A5`,
|
|
137
|
+
'```',
|
|
138
|
+
'',
|
|
139
|
+
'',
|
|
140
|
+
),
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const meta: Meta = {
|
|
145
|
+
title: 'plugins/plugin-sheet/extensions',
|
|
146
|
+
decorators: [
|
|
147
|
+
withClientProvider({ types: [SheetType], createIdentity: true, createSpace: true }),
|
|
148
|
+
withComputeGraphDecorator(),
|
|
149
|
+
withTheme,
|
|
150
|
+
withLayout({ fullscreen: true, classNames: 'justify-center' }),
|
|
151
|
+
],
|
|
152
|
+
parameters: { layout: 'fullscreen' },
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
export default meta;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { syntaxTree } from '@codemirror/language';
|
|
6
|
+
import {
|
|
7
|
+
type EditorState,
|
|
8
|
+
type Extension,
|
|
9
|
+
type RangeSet,
|
|
10
|
+
RangeSetBuilder,
|
|
11
|
+
StateEffect,
|
|
12
|
+
StateField,
|
|
13
|
+
type Transaction,
|
|
14
|
+
} from '@codemirror/state';
|
|
15
|
+
import { Decoration, EditorView, ViewPlugin, WidgetType } from '@codemirror/view';
|
|
16
|
+
|
|
17
|
+
import { type UnsubscribeCallback, debounce } from '@dxos/async';
|
|
18
|
+
import { invariant } from '@dxos/invariant';
|
|
19
|
+
import { documentId, singleValueFacet } from '@dxos/react-ui-editor/state';
|
|
20
|
+
|
|
21
|
+
import { type CellAddress } from '../defs';
|
|
22
|
+
import { type ComputeGraph, type ComputeNode, createSheetName } from '../graph';
|
|
23
|
+
import { type CellScalarValue } from '../types';
|
|
24
|
+
|
|
25
|
+
const LANGUAGE_TAG = 'dx';
|
|
26
|
+
|
|
27
|
+
// TODO(burdon): Create marker just for our decorator?
|
|
28
|
+
const updateAllDecorations = StateEffect.define<void>();
|
|
29
|
+
|
|
30
|
+
export const computeGraphFacet = singleValueFacet<ComputeGraph>();
|
|
31
|
+
|
|
32
|
+
export type ComputeOptions = {};
|
|
33
|
+
|
|
34
|
+
export const compute = (options: ComputeOptions = {}): Extension => {
|
|
35
|
+
let computeNode: ComputeNode | undefined;
|
|
36
|
+
|
|
37
|
+
const update = (state: EditorState, current?: RangeSet<Decoration>) => {
|
|
38
|
+
const builder = new RangeSetBuilder<Decoration>();
|
|
39
|
+
if (computeNode) {
|
|
40
|
+
computeNode.clear();
|
|
41
|
+
syntaxTree(state).iterate({
|
|
42
|
+
enter: (node) => {
|
|
43
|
+
switch (node.name) {
|
|
44
|
+
case 'FencedCode': {
|
|
45
|
+
const cursor = state.selection.main.head;
|
|
46
|
+
if (state.readOnly || cursor < node.from || cursor > node.to) {
|
|
47
|
+
const info = node.node.getChild('CodeInfo');
|
|
48
|
+
if (info) {
|
|
49
|
+
const type = state.sliceDoc(info.from, info.to);
|
|
50
|
+
const text = node.node.getChild('CodeText');
|
|
51
|
+
if (type === LANGUAGE_TAG && text) {
|
|
52
|
+
const formula = state.sliceDoc(text.from, text.to);
|
|
53
|
+
|
|
54
|
+
const iter = current?.iter(node.node.from);
|
|
55
|
+
if (iter?.value && iter?.value.spec.formula === formula) {
|
|
56
|
+
// Add existing widget.
|
|
57
|
+
builder.add(node.from, node.to, iter.value);
|
|
58
|
+
} else {
|
|
59
|
+
// TODO(burdon): Create ordered list of cells on each decoration run.
|
|
60
|
+
const cell: CellAddress = { col: node.node.from, row: 0 };
|
|
61
|
+
invariant(computeNode);
|
|
62
|
+
// NOTE: This triggers re-render (below).
|
|
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 ComputeWidget(formula, value),
|
|
70
|
+
formula,
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return builder.finish();
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
return [
|
|
89
|
+
ViewPlugin.fromClass(
|
|
90
|
+
class {
|
|
91
|
+
// Graph subscription.
|
|
92
|
+
private _subscription?: UnsubscribeCallback;
|
|
93
|
+
constructor(view: EditorView) {
|
|
94
|
+
const id = view.state.facet(documentId);
|
|
95
|
+
const computeGraph = view.state.facet(computeGraphFacet);
|
|
96
|
+
if (id && computeGraph) {
|
|
97
|
+
queueMicrotask(async () => {
|
|
98
|
+
computeNode = computeGraph.getOrCreateNode(createSheetName({ type: '', id }));
|
|
99
|
+
await computeNode.open();
|
|
100
|
+
|
|
101
|
+
// Trigger re-render if values updated.
|
|
102
|
+
// TODO(burdon): Trigger only if formula value updated (currently triggered during render).
|
|
103
|
+
this._subscription = computeNode.update.on(
|
|
104
|
+
debounce(({ type, ...rest }) => {
|
|
105
|
+
if (type === 'valuesUpdated') {
|
|
106
|
+
view.dispatch({
|
|
107
|
+
effects: updateAllDecorations.of(),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}, 250),
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
destroy() {
|
|
117
|
+
this._subscription?.();
|
|
118
|
+
void computeNode?.close();
|
|
119
|
+
computeNode = undefined;
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
),
|
|
123
|
+
|
|
124
|
+
StateField.define<RangeSet<Decoration>>({
|
|
125
|
+
create: (state) => update(state),
|
|
126
|
+
update: (rangeSet: RangeSet<Decoration>, tr: Transaction) => update(tr.state, rangeSet),
|
|
127
|
+
provide: (field) => EditorView.decorations.from(field),
|
|
128
|
+
}),
|
|
129
|
+
];
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// TODO(burdon): Click to edit.
|
|
133
|
+
class ComputeWidget extends WidgetType {
|
|
134
|
+
constructor(
|
|
135
|
+
private readonly formula: string,
|
|
136
|
+
private readonly value: CellScalarValue,
|
|
137
|
+
) {
|
|
138
|
+
super();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
override toDOM(_view: EditorView) {
|
|
142
|
+
const div = document.createElement('div');
|
|
143
|
+
div.setAttribute('title', this.formula);
|
|
144
|
+
div.innerText = String(this.value);
|
|
145
|
+
return div;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
@@ -4,14 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
import { CompletionContext, type CompletionSource } from '@codemirror/autocomplete';
|
|
6
6
|
import { EditorState } from '@codemirror/state';
|
|
7
|
-
// @ts-ignore
|
|
8
7
|
import { testTree } from '@lezer/generator/test';
|
|
9
|
-
import { expect } from 'chai';
|
|
10
8
|
import { spreadsheet } from 'codemirror-lang-spreadsheet';
|
|
11
|
-
import { describe, test } from 'vitest';
|
|
9
|
+
import { describe, expect, test } from 'vitest';
|
|
12
10
|
|
|
13
11
|
import { sheetExtension } from './extension';
|
|
14
|
-
import { defaultFunctions } from '../../
|
|
12
|
+
import { defaultFunctions } from '../../graph';
|
|
15
13
|
|
|
16
14
|
describe('formula parser', () => {
|
|
17
15
|
const {
|
|
@@ -37,8 +35,8 @@ describe('formula parser', () => {
|
|
|
37
35
|
extensions: sheetExtension({ functions }),
|
|
38
36
|
});
|
|
39
37
|
|
|
40
|
-
const [
|
|
41
|
-
const result = await
|
|
38
|
+
const [fn] = state.languageDataAt<CompletionSource>('autocomplete', text.length);
|
|
39
|
+
const result = await fn(new CompletionContext(state, text.length, true));
|
|
42
40
|
expect(result?.options).to.have.length(1);
|
|
43
41
|
});
|
|
44
42
|
});
|
|
@@ -12,15 +12,16 @@ import {
|
|
|
12
12
|
startCompletion,
|
|
13
13
|
} from '@codemirror/autocomplete';
|
|
14
14
|
import { HighlightStyle, type Language, syntaxHighlighting } from '@codemirror/language';
|
|
15
|
-
import { type Extension
|
|
15
|
+
import { type Extension } from '@codemirror/state';
|
|
16
16
|
import { type EditorView, ViewPlugin, type ViewUpdate, keymap } from '@codemirror/view';
|
|
17
17
|
import { type SyntaxNode } from '@lezer/common';
|
|
18
18
|
import { tags } from '@lezer/highlight';
|
|
19
19
|
import { spreadsheet } from 'codemirror-lang-spreadsheet';
|
|
20
20
|
|
|
21
|
+
import { singleValueFacet } from '@dxos/react-ui-editor/state';
|
|
21
22
|
import { mx } from '@dxos/react-ui-theme';
|
|
22
23
|
|
|
23
|
-
import { type FunctionDefinition } from '../../
|
|
24
|
+
import { type FunctionDefinition } from '../../graph';
|
|
24
25
|
|
|
25
26
|
/**
|
|
26
27
|
* https://codemirror.net/examples/styling
|
|
@@ -59,7 +60,7 @@ const highlightStyles = HighlightStyle.define([
|
|
|
59
60
|
},
|
|
60
61
|
]);
|
|
61
62
|
|
|
62
|
-
const languageFacet =
|
|
63
|
+
const languageFacet = singleValueFacet<Language>();
|
|
63
64
|
|
|
64
65
|
export type SheetExtensionOptions = {
|
|
65
66
|
functions?: FunctionDefinition[];
|
|
@@ -165,8 +166,6 @@ export const sheetExtension = ({ functions = [] }: SheetExtensionOptions): Exten
|
|
|
165
166
|
icons: false,
|
|
166
167
|
tooltipClass: () =>
|
|
167
168
|
mx(
|
|
168
|
-
// TODO(burdon): Factor out fragments.
|
|
169
|
-
// TODO(burdon): Size to make width same as column.
|
|
170
169
|
'!-left-[1px] !top-[33px] !-m-0 border !border-t-0 [&>ul]:!min-w-[198px]',
|
|
171
170
|
'[&>ul>li[aria-selected]]:!bg-accentSurface',
|
|
172
171
|
'border-separator',
|
|
@@ -231,7 +230,7 @@ export const rangeExtension = (onInit: (notifier: CellRangeNotifier) => void): E
|
|
|
231
230
|
|
|
232
231
|
// Find first Range or cell at cursor.
|
|
233
232
|
activeRange = undefined;
|
|
234
|
-
const
|
|
233
|
+
const language = view.state.facet(languageFacet);
|
|
235
234
|
const { topNode } = language.parser.parse(view.state.doc.toString());
|
|
236
235
|
visitTree(topNode, ({ type, from, to }) => {
|
|
237
236
|
if (from <= anchor && to >= anchor) {
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import type { FunctionPluginDefinition } from 'hyperformula';
|
|
6
|
+
import type { ConfigParams } from 'hyperformula/typings/ConfigParams';
|
|
7
|
+
import type { FunctionTranslationsPackage } from 'hyperformula/typings/interpreter';
|
|
8
|
+
import defaultsDeep from 'lodash.defaultsdeep';
|
|
9
|
+
|
|
10
|
+
import { type SpaceId, type Space } from '@dxos/client/echo';
|
|
11
|
+
import { Resource } from '@dxos/context';
|
|
12
|
+
import { invariant } from '@dxos/invariant';
|
|
13
|
+
import { log } from '@dxos/log';
|
|
14
|
+
|
|
15
|
+
import { HyperFormula } from '#hyperformula';
|
|
16
|
+
import { ComputeGraph } from './compute-graph';
|
|
17
|
+
import { EdgeFunctionPlugin, EdgeFunctionPluginTranslations, type FunctionContextOptions } from './functions';
|
|
18
|
+
|
|
19
|
+
export type ComputeGraphPlugin = {
|
|
20
|
+
plugin: FunctionPluginDefinition;
|
|
21
|
+
translations: FunctionTranslationsPackage;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export type ComputeGraphOptions = {
|
|
25
|
+
plugins?: ComputeGraphPlugin[];
|
|
26
|
+
} & Partial<FunctionContextOptions> &
|
|
27
|
+
Partial<ConfigParams>;
|
|
28
|
+
|
|
29
|
+
export const defaultOptions: ComputeGraphOptions = {
|
|
30
|
+
licenseKey: 'gpl-v3',
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const defaultPlugins: ComputeGraphPlugin[] = [
|
|
34
|
+
{
|
|
35
|
+
plugin: EdgeFunctionPlugin,
|
|
36
|
+
translations: EdgeFunctionPluginTranslations,
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Manages a collection of ComputeGraph instances for each space.
|
|
42
|
+
*
|
|
43
|
+
* [ComputePlugin] => [ComputeGraphRegistry] => [ComputeGraph(Space)] => [ComputeNode(Object)]
|
|
44
|
+
*
|
|
45
|
+
* NOTE: The ComputeGraphRegistry manages the hierarchy of resources via its root Context.
|
|
46
|
+
* NOTE: The package.json file defines the packaged #hyperformula module.
|
|
47
|
+
*/
|
|
48
|
+
// TODO(burdon): Move graph into separate plugin; isolate HF deps.
|
|
49
|
+
export class ComputeGraphRegistry extends Resource {
|
|
50
|
+
private readonly _graphs = new Map<SpaceId, ComputeGraph>();
|
|
51
|
+
|
|
52
|
+
private readonly _options: ComputeGraphOptions;
|
|
53
|
+
|
|
54
|
+
constructor(options: ComputeGraphOptions = { plugins: defaultPlugins }) {
|
|
55
|
+
super();
|
|
56
|
+
this._options = defaultsDeep({}, options, defaultOptions);
|
|
57
|
+
this._options.plugins?.forEach(({ plugin, translations }) => {
|
|
58
|
+
HyperFormula.registerFunctionPlugin(plugin, translations);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getGraph(spaceId: SpaceId): ComputeGraph | undefined {
|
|
63
|
+
return this._graphs.get(spaceId);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
getOrCreateGraph(space: Space): ComputeGraph {
|
|
67
|
+
let graph = this._graphs.get(space.id);
|
|
68
|
+
if (!graph) {
|
|
69
|
+
log('create graph', { space: space.id });
|
|
70
|
+
graph = this.createGraph(space);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return graph;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
createGraph(space: Space): ComputeGraph {
|
|
77
|
+
invariant(!this._graphs.has(space.id), `ComputeGraph already exists for space: ${space.id}`);
|
|
78
|
+
const hf = HyperFormula.buildEmpty(this._options);
|
|
79
|
+
const graph = new ComputeGraph(hf, space, this._options);
|
|
80
|
+
this._graphs.set(space.id, graph);
|
|
81
|
+
return graph;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
protected override async _close() {
|
|
85
|
+
for (const graph of this._graphs.values()) {
|
|
86
|
+
await graph.close();
|
|
87
|
+
}
|
|
88
|
+
this._graphs.clear();
|
|
89
|
+
}
|
|
90
|
+
}
|