@dxos/plugin-sheet 0.6.12-main.15a606f → 0.6.12-main.2d19bf1
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-NDNIS44E.mjs +265 -0
- package/dist/lib/browser/SheetContainer-NDNIS44E.mjs.map +7 -0
- package/dist/lib/browser/chunk-AQSGDA4X.mjs +1614 -0
- package/dist/lib/browser/chunk-AQSGDA4X.mjs.map +7 -0
- package/dist/lib/browser/{chunk-QILRZNE5.mjs → chunk-D3QTX46O.mjs} +4 -5
- package/dist/lib/browser/chunk-D3QTX46O.mjs.map +7 -0
- package/dist/lib/browser/{chunk-T3NJFTD4.mjs → chunk-GKI67SEF.mjs} +20 -26
- package/dist/lib/browser/chunk-GKI67SEF.mjs.map +7 -0
- package/dist/lib/browser/{chunk-6ZMQVB4Z.mjs → chunk-GSV5QNLD.mjs} +220 -177
- package/dist/lib/browser/chunk-GSV5QNLD.mjs.map +7 -0
- package/dist/lib/browser/graph-M4IQ76QX.mjs +33 -0
- package/dist/lib/browser/index.mjs +41 -22
- 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 +4 -8
- package/dist/lib/node/SheetContainer-YSQGJD7K.cjs +276 -0
- package/dist/lib/node/SheetContainer-YSQGJD7K.cjs.map +7 -0
- package/dist/lib/node/{chunk-DD6FIXWC.cjs → chunk-5XPK2V4A.cjs} +222 -175
- package/dist/lib/node/chunk-5XPK2V4A.cjs.map +7 -0
- package/dist/lib/node/chunk-6F43RV45.cjs +1610 -0
- package/dist/lib/node/chunk-6F43RV45.cjs.map +7 -0
- package/dist/lib/node/{chunk-Q3HBHPRL.cjs → chunk-ER3PM7GD.cjs} +26 -34
- package/dist/lib/node/chunk-ER3PM7GD.cjs.map +7 -0
- package/dist/lib/node/{chunk-BNARJ5GM.cjs → chunk-QIFIGEKV.cjs} +6 -7
- 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 +61 -44
- 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 +8 -12
- package/dist/lib/node/types.cjs.map +2 -2
- package/dist/lib/node-esm/SheetContainer-M7WRMZDU.mjs +266 -0
- package/dist/lib/node-esm/SheetContainer-M7WRMZDU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-D6KU5MI7.mjs → chunk-5WPZCXNS.mjs} +220 -177
- package/dist/lib/node-esm/chunk-5WPZCXNS.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-ELTFPX5B.mjs +1615 -0
- package/dist/lib/node-esm/chunk-ELTFPX5B.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-IU2L277A.mjs → chunk-VCYJWE3O.mjs} +4 -5
- package/dist/lib/node-esm/chunk-VCYJWE3O.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-BMNA27EX.mjs → chunk-ZVLLQ2PJ.mjs} +20 -26
- package/dist/lib/node-esm/chunk-ZVLLQ2PJ.mjs.map +7 -0
- package/dist/lib/node-esm/graph-SMPUMOV2.mjs +34 -0
- package/dist/lib/node-esm/index.mjs +41 -22
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/meta.mjs +1 -1
- package/dist/lib/node-esm/types.mjs +4 -8
- package/dist/types/src/SheetPlugin.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 +1 -8
- package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -1
- package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +1 -1
- package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -1
- package/dist/types/src/components/{CellEditor/CellEditor.stories.d.ts → GridSheet/SheetCellEditor.stories.d.ts} +2 -2
- 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 +13 -3
- package/dist/types/src/components/GridSheet/util.d.ts.map +1 -1
- 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 +11 -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 +27 -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 +31 -17
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +1 -1
- package/dist/types/src/components/index.d.ts +3 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/defs/types.d.ts.map +1 -1
- package/dist/types/src/defs/util.d.ts +1 -1
- package/dist/types/src/defs/util.d.ts.map +1 -1
- package/dist/types/src/extensions/compute.d.ts +3 -2
- package/dist/types/src/extensions/compute.d.ts.map +1 -1
- package/dist/types/src/extensions/compute.stories.d.ts.map +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 +1 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -1
- 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 +17 -34
- package/dist/types/src/graph/compute-graph.d.ts.map +1 -1
- package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -1
- 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 +9 -2
- package/dist/types/src/graph/compute-node.d.ts.map +1 -1
- package/dist/types/src/graph/{async-function.d.ts → functions/async-function.d.ts} +13 -4
- 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/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/index.d.ts +2 -1
- package/dist/types/src/graph/index.d.ts.map +1 -1
- 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/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- 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.map +1 -1
- package/dist/types/src/hooks/useSheetModel.d.ts +2 -2
- package/dist/types/src/hooks/useSheetModel.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +3 -6
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/{components/Sheet → model}/decorations.d.ts +1 -0
- package/dist/types/src/model/decorations.d.ts.map +1 -0
- package/dist/types/src/model/formatting-model.d.ts +3 -0
- package/dist/types/src/model/formatting-model.d.ts.map +1 -1
- package/dist/types/src/model/index.d.ts +1 -0
- package/dist/types/src/model/index.d.ts.map +1 -1
- package/dist/types/src/model/sheet-model.d.ts +6 -5
- package/dist/types/src/model/sheet-model.d.ts.map +1 -1
- 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/testing/testing.d.ts +4 -5
- package/dist/types/src/testing/testing.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +17 -31
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +42 -41
- package/src/SheetPlugin.tsx +22 -17
- package/src/components/FunctionEditor/FunctionEditor.tsx +45 -0
- package/src/components/FunctionEditor/index.ts +5 -0
- package/src/components/GridSheet/GridSheet.stories.tsx +11 -5
- package/src/components/GridSheet/GridSheet.tsx +78 -70
- package/src/components/{CellEditor/CellEditor.stories.tsx → GridSheet/SheetCellEditor.stories.tsx} +4 -5
- package/src/components/{Sheet → GridSheet}/index.ts +1 -1
- package/src/components/GridSheet/util.ts +94 -39
- package/src/components/SheetContainer/SheetContainer.stories.tsx +40 -0
- package/src/components/SheetContainer/SheetContainer.tsx +52 -0
- package/src/components/SheetContainer/index.ts +7 -0
- package/src/components/{Sheet/sheet-context.tsx → SheetContext/SheetContext.tsx} +48 -28
- package/src/components/SheetContext/index.ts +5 -0
- package/src/components/Toolbar/Toolbar.tsx +127 -86
- package/src/components/index.ts +2 -1
- package/src/defs/types.ts +1 -0
- package/src/defs/util.ts +20 -4
- package/src/extensions/compute.stories.tsx +23 -23
- package/src/extensions/compute.ts +91 -42
- package/src/{components/CellEditor → extensions/editor}/extension.test.ts +0 -1
- package/src/{components/CellEditor → extensions/editor}/extension.ts +4 -3
- package/src/{components/CellEditor → extensions/editor}/index.ts +0 -1
- package/src/extensions/index.ts +1 -0
- package/src/graph/compute-graph-registry.ts +90 -0
- package/src/graph/compute-graph.stories.tsx +4 -3
- package/src/graph/compute-graph.test.ts +87 -0
- package/src/graph/compute-graph.ts +73 -121
- package/src/graph/compute-node.ts +17 -5
- package/src/graph/{async-function.ts → functions/async-function.ts} +23 -15
- package/src/graph/{edge-function.ts → functions/edge-function.ts} +14 -13
- package/src/graph/functions/index.ts +7 -0
- package/src/graph/hyperformula.test.ts +1 -2
- package/src/graph/index.ts +2 -1
- package/src/graph/testing/index.ts +6 -0
- package/src/graph/testing/test-builder.ts +54 -0
- package/src/graph/{custom-function.ts → testing/test-plugin.ts} +43 -9
- package/src/hooks/hooks.stories.tsx +3 -3
- package/src/hooks/index.ts +1 -0
- package/src/{components/Sheet/threads.tsx → hooks/threads.ts} +26 -84
- package/src/hooks/useComputeGraph.ts +9 -1
- package/src/hooks/useSheetModel.ts +4 -7
- package/src/{meta.tsx → meta.ts} +3 -3
- package/src/{components/Sheet → model}/decorations.ts +2 -0
- package/src/model/formatting-model.ts +12 -9
- package/src/model/index.ts +1 -0
- package/src/model/sheet-model.test.ts +57 -0
- package/src/model/sheet-model.ts +60 -41
- package/src/testing/testing.tsx +17 -15
- package/src/types.ts +12 -38
- package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs +0 -261
- package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs.map +0 -7
- package/dist/lib/browser/chunk-6ZMQVB4Z.mjs.map +0 -7
- package/dist/lib/browser/chunk-QILRZNE5.mjs.map +0 -7
- package/dist/lib/browser/chunk-T3NJFTD4.mjs.map +0 -7
- package/dist/lib/browser/chunk-U2JHW3L6.mjs +0 -2552
- package/dist/lib/browser/chunk-U2JHW3L6.mjs.map +0 -7
- package/dist/lib/browser/graph-T27BOBOV.mjs +0 -21
- package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs +0 -279
- package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs.map +0 -7
- package/dist/lib/node/chunk-BNARJ5GM.cjs.map +0 -7
- package/dist/lib/node/chunk-DD6FIXWC.cjs.map +0 -7
- package/dist/lib/node/chunk-OTTD7FBK.cjs +0 -2536
- package/dist/lib/node/chunk-OTTD7FBK.cjs.map +0 -7
- package/dist/lib/node/chunk-Q3HBHPRL.cjs.map +0 -7
- package/dist/lib/node/graph-SPKGX7W4.cjs +0 -43
- package/dist/lib/node/graph-SPKGX7W4.cjs.map +0 -7
- package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs +0 -262
- package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-7HVSOTGA.mjs +0 -2553
- package/dist/lib/node-esm/chunk-7HVSOTGA.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-BMNA27EX.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-D6KU5MI7.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +0 -7
- package/dist/lib/node-esm/graph-U67IO4UC.mjs +0 -22
- package/dist/types/src/components/CellEditor/CellEditor.d.ts +0 -34
- 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/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 -53
- package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/decorations.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 -26
- package/dist/types/src/components/Sheet/sheet-context.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/threads.d.ts +0 -2
- package/dist/types/src/components/Sheet/threads.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 -8
- 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/graph/async-function.d.ts.map +0 -1
- package/dist/types/src/graph/compute-graph.browser.test.d.ts +0 -2
- package/dist/types/src/graph/compute-graph.browser.test.d.ts.map +0 -1
- package/dist/types/src/graph/custom-function.d.ts +0 -21
- package/dist/types/src/graph/custom-function.d.ts.map +0 -1
- package/dist/types/src/graph/edge-function.d.ts +0 -20
- package/dist/types/src/graph/edge-function.d.ts.map +0 -1
- package/dist/types/src/graph/function-defs.d.ts.map +0 -1
- package/src/components/CellEditor/CellEditor.tsx +0 -163
- package/src/components/Sheet/Sheet.stories.tsx +0 -250
- package/src/components/Sheet/Sheet.tsx +0 -1199
- package/src/components/Sheet/grid.ts +0 -191
- package/src/components/Sheet/nav.ts +0 -157
- package/src/components/Sheet/util.ts +0 -56
- package/src/components/SheetContainer.tsx +0 -88
- package/src/components/Toolbar/common.tsx +0 -72
- package/src/graph/compute-graph.browser.test.ts +0 -104
- /package/dist/lib/browser/{graph-T27BOBOV.mjs.map → graph-M4IQ76QX.mjs.map} +0 -0
- /package/dist/lib/node-esm/{graph-U67IO4UC.mjs.map → graph-SMPUMOV2.mjs.map} +0 -0
- /package/dist/types/src/{components/CellEditor → extensions/editor}/extension.d.ts +0 -0
- /package/dist/types/src/{components/CellEditor → extensions/editor}/extension.test.d.ts +0 -0
- /package/dist/types/src/graph/{function-defs.d.ts → functions/function-defs.d.ts} +0 -0
- /package/src/graph/{function-defs.ts → functions/function-defs.ts} +0 -0
|
@@ -14,85 +14,134 @@ import {
|
|
|
14
14
|
} from '@codemirror/state';
|
|
15
15
|
import { Decoration, EditorView, ViewPlugin, WidgetType } from '@codemirror/view';
|
|
16
16
|
|
|
17
|
-
import { type
|
|
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';
|
|
18
24
|
|
|
19
25
|
const LANGUAGE_TAG = 'dx';
|
|
20
26
|
|
|
21
27
|
// TODO(burdon): Create marker just for our decorator?
|
|
22
28
|
const updateAllDecorations = StateEffect.define<void>();
|
|
23
29
|
|
|
30
|
+
export const computeGraphFacet = singleValueFacet<ComputeGraph>();
|
|
31
|
+
|
|
24
32
|
export type ComputeOptions = {};
|
|
25
33
|
|
|
26
|
-
export const compute = (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
+
}
|
|
50
76
|
}
|
|
77
|
+
|
|
78
|
+
break;
|
|
51
79
|
}
|
|
52
80
|
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
}
|
|
56
84
|
|
|
57
85
|
return builder.finish();
|
|
58
86
|
};
|
|
59
87
|
|
|
60
88
|
return [
|
|
61
|
-
// Graph subscription.
|
|
62
89
|
ViewPlugin.fromClass(
|
|
63
90
|
class {
|
|
64
|
-
|
|
91
|
+
// Graph subscription.
|
|
92
|
+
private _subscription?: UnsubscribeCallback;
|
|
65
93
|
constructor(view: EditorView) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
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
|
+
);
|
|
69
112
|
});
|
|
70
|
-
}
|
|
113
|
+
}
|
|
71
114
|
}
|
|
72
115
|
|
|
73
116
|
destroy() {
|
|
74
|
-
this._subscription();
|
|
117
|
+
this._subscription?.();
|
|
118
|
+
void computeNode?.close();
|
|
119
|
+
computeNode = undefined;
|
|
75
120
|
}
|
|
76
121
|
},
|
|
77
122
|
),
|
|
78
123
|
|
|
79
|
-
|
|
80
|
-
StateField.define<RangeSet<any>>({
|
|
124
|
+
StateField.define<RangeSet<Decoration>>({
|
|
81
125
|
create: (state) => update(state),
|
|
82
|
-
update: (
|
|
126
|
+
update: (rangeSet: RangeSet<Decoration>, tr: Transaction) => update(tr.state, rangeSet),
|
|
83
127
|
provide: (field) => EditorView.decorations.from(field),
|
|
84
128
|
}),
|
|
85
129
|
];
|
|
86
130
|
};
|
|
87
131
|
|
|
88
|
-
|
|
89
|
-
|
|
132
|
+
// TODO(burdon): Click to edit.
|
|
133
|
+
class ComputeWidget extends WidgetType {
|
|
134
|
+
constructor(
|
|
135
|
+
private readonly formula: string,
|
|
136
|
+
private readonly value: CellScalarValue,
|
|
137
|
+
) {
|
|
90
138
|
super();
|
|
91
139
|
}
|
|
92
140
|
|
|
93
|
-
override toDOM(
|
|
141
|
+
override toDOM(_view: EditorView) {
|
|
94
142
|
const div = document.createElement('div');
|
|
95
|
-
div.
|
|
143
|
+
div.setAttribute('title', this.formula);
|
|
144
|
+
div.innerText = String(this.value);
|
|
96
145
|
return div;
|
|
97
146
|
}
|
|
98
147
|
}
|
|
@@ -4,7 +4,6 @@
|
|
|
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
8
|
import { spreadsheet } from 'codemirror-lang-spreadsheet';
|
|
10
9
|
import { describe, expect, test } from 'vitest';
|
|
@@ -12,12 +12,13 @@ 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
24
|
import { type FunctionDefinition } from '../../graph';
|
|
@@ -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[];
|
|
@@ -229,7 +230,7 @@ export const rangeExtension = (onInit: (notifier: CellRangeNotifier) => void): E
|
|
|
229
230
|
|
|
230
231
|
// Find first Range or cell at cursor.
|
|
231
232
|
activeRange = undefined;
|
|
232
|
-
const
|
|
233
|
+
const language = view.state.facet(languageFacet);
|
|
233
234
|
const { topNode } = language.parser.parse(view.state.doc.toString());
|
|
234
235
|
visitTree(topNode, ({ type, from, to }) => {
|
|
235
236
|
if (from <= anchor && to >= anchor) {
|
package/src/extensions/index.ts
CHANGED
|
@@ -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
|
+
}
|
|
@@ -13,9 +13,10 @@ import { Toolbar, Button, Input } from '@dxos/react-ui';
|
|
|
13
13
|
import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
14
14
|
import { withTheme } from '@dxos/storybook-utils';
|
|
15
15
|
|
|
16
|
+
import { testFunctionPlugins } from './testing';
|
|
16
17
|
import { createSheet } from '../defs';
|
|
17
18
|
import { useComputeGraph, useSheetModel } from '../hooks';
|
|
18
|
-
import {
|
|
19
|
+
import { withComputeGraphDecorator } from '../testing';
|
|
19
20
|
import { SheetType } from '../types';
|
|
20
21
|
|
|
21
22
|
const FUNCTION_NAME = 'TEST';
|
|
@@ -26,7 +27,7 @@ const Story = () => {
|
|
|
26
27
|
const [sheet, setSheet] = useState<SheetType>();
|
|
27
28
|
const [text, setText] = useState(`${FUNCTION_NAME}(100)`);
|
|
28
29
|
const [result, setResult] = useState<any>();
|
|
29
|
-
const model = useSheetModel(
|
|
30
|
+
const model = useSheetModel(graph, sheet);
|
|
30
31
|
useEffect(() => {
|
|
31
32
|
if (space) {
|
|
32
33
|
const sheet = space.db.add(createSheet());
|
|
@@ -83,7 +84,7 @@ export default {
|
|
|
83
84
|
title: 'plugin-sheet/functions',
|
|
84
85
|
decorators: [
|
|
85
86
|
withClientProvider({ types: [FunctionType, SheetType], createIdentity: true, createSpace: true }),
|
|
86
|
-
|
|
87
|
+
withComputeGraphDecorator({ plugins: testFunctionPlugins }),
|
|
87
88
|
withTheme,
|
|
88
89
|
],
|
|
89
90
|
render: (args: any) => <Story {...args} />,
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type CellValue } from 'hyperformula';
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, test } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import { Trigger } from '@dxos/async';
|
|
9
|
+
import { create, fullyQualifiedId } from '@dxos/client/echo';
|
|
10
|
+
import { FunctionType } from '@dxos/plugin-script/types';
|
|
11
|
+
|
|
12
|
+
import { DetailedCellError } from '#hyperformula';
|
|
13
|
+
import { TestBuilder } from './testing';
|
|
14
|
+
|
|
15
|
+
describe('ComputeGraph', () => {
|
|
16
|
+
let testBuilder: TestBuilder;
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
testBuilder = new TestBuilder({ types: [FunctionType] });
|
|
19
|
+
await testBuilder.open();
|
|
20
|
+
});
|
|
21
|
+
afterEach(async () => {
|
|
22
|
+
await testBuilder.close();
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('map functions', async () => {
|
|
26
|
+
const space = await testBuilder.client.spaces.create();
|
|
27
|
+
const graph = testBuilder.registry.createGraph(space);
|
|
28
|
+
await graph.open();
|
|
29
|
+
|
|
30
|
+
// Create script.
|
|
31
|
+
const trigger = new Trigger();
|
|
32
|
+
graph.update.once(() => trigger.wake());
|
|
33
|
+
const functionObject = space.db.add(create(FunctionType, { version: 1, binding: 'TEST' }));
|
|
34
|
+
await trigger.wait();
|
|
35
|
+
const functions = graph.getFunctions({ echo: true });
|
|
36
|
+
expect(functions).to.toHaveLength(1);
|
|
37
|
+
|
|
38
|
+
const id = graph.mapFunctionBindingToId('TEST()');
|
|
39
|
+
expect(id).to.eq(`${fullyQualifiedId(functionObject)}()`);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('cross-node references', async () => {
|
|
43
|
+
const space = await testBuilder.client.spaces.create();
|
|
44
|
+
const graph = testBuilder.registry.createGraph(space);
|
|
45
|
+
|
|
46
|
+
// Create nodes.
|
|
47
|
+
const node1 = await graph.getOrCreateNode('node-1').open();
|
|
48
|
+
const node2 = await graph.getOrCreateNode('node-2').open();
|
|
49
|
+
expect(graph.hf.getSheetNames()).to.toHaveLength(2);
|
|
50
|
+
|
|
51
|
+
{
|
|
52
|
+
node1.graph.hf.setCellContents({ sheet: node1.sheetId, row: 0, col: 0 }, [[100, 200, 300, '=SUM(A1:C1)']]);
|
|
53
|
+
node2.graph.hf.setCellContents({ sheet: node2.sheetId, row: 0, col: 0 }, "='node-1'!D1");
|
|
54
|
+
const value1 = node1.graph.hf.getCellValue({ sheet: node1.sheetId, col: 3, row: 0 });
|
|
55
|
+
const value2 = node2.graph.hf.getCellValue({ sheet: node2.sheetId, col: 0, row: 0 });
|
|
56
|
+
expect(value1).to.eq(value2);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Get updated event.
|
|
60
|
+
const trigger = new Trigger<CellValue>();
|
|
61
|
+
node2.update.on(({ change }) => {
|
|
62
|
+
const value = node2.graph.hf.getCellValue({ sheet: node2.sheetId, col: 0, row: 0 });
|
|
63
|
+
expect(value).to.eq(change?.newValue);
|
|
64
|
+
trigger.wake(value);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
{
|
|
68
|
+
node1.graph.hf.setCellContents({ sheet: node1.sheetId, row: 0, col: 0 }, 400);
|
|
69
|
+
const value1 = node1.graph.hf.getCellValue({ sheet: node1.sheetId, col: 3, row: 0 });
|
|
70
|
+
const value2 = await trigger.wait();
|
|
71
|
+
expect(value1).to.eq(value2);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
// TODO(burdon): Dynamically load node/model based on dependencies.
|
|
76
|
+
// - Create dependency then close model.
|
|
77
|
+
test('dynamic loading', async () => {
|
|
78
|
+
const space = await testBuilder.client.spaces.create();
|
|
79
|
+
const graph = testBuilder.registry.createGraph(space);
|
|
80
|
+
|
|
81
|
+
const node1 = await graph.getOrCreateNode('node-1').open();
|
|
82
|
+
node1.graph.hf.setCellContents({ sheet: node1.sheetId, row: 0, col: 0 }, "='node-2'!A1");
|
|
83
|
+
const value1 = node1.graph.hf.getCellValue({ sheet: node1.sheetId, col: 0, row: 0 });
|
|
84
|
+
expect(value1).to.be.instanceof(DetailedCellError);
|
|
85
|
+
expect((value1 as DetailedCellError).type).to.eq('REF');
|
|
86
|
+
});
|
|
87
|
+
});
|